Files
adas-core/adas-core.Test/Repositories/AlarmRepositoryTest.cs
T

273 lines
10 KiB
C#

using adas_core.Domain.Models;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.GroupedObservations;
using adas_core.Infrastructure.Repositories;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using Moq;
using Options = Microsoft.Extensions.Options.Options;
namespace adas_core.Test.Repositories;
/// <summary>
/// Integration test fixture that validates the behavior of <see cref="AlarmRepository"/>.
/// </summary>
/// <remarks>
/// Annotated with <see cref="NUnit.Framework.TestFixtureAttribute"/>, <see cref="NUnit.Framework.OrderAttribute"/>, and <see cref="NUnit.Framework.CategoryAttribute"/> to control execution ordering and group the tests under the integration category.
/// </remarks>
/// <!-- aidoc:v1 sig=b6895d1 -->
[TestFixture]
[Order(1)]
[Category("Integration")]
public class AlarmRepositoryTest
{
/// <summary>
/// One-time test setup that initializes the alarm repository with two sample
/// <see cref="PatientObservationAlarm"/> records by resetting the target
/// collection and inserting the test data for use across the test fixture.
/// </summary>
/// <!-- aidoc:v1 sig=81c0015 body=0cc6054 -->
[OneTimeSetUp]
public async Task Init()
{
_optionsApiSettings = Options.Create(_apiSettings);
var pObsAlarm1 = new PatientObservationAlarm
{
Id = Id,
PatientId = PatientId,
Code = "code1",
CodingSystem = "SNM",
Name = "name1",
Time = Now,
Value = "value1",
SystemId = "systemId1"
};
var pObsAlarm2 = new PatientObservationAlarm
{
Id = ObjectId.GenerateNewId(),
PatientId = PatientId,
Code = "code2",
CodingSystem = "SNM",
Name = "name2",
Time = Now,
Value = "value2",
SystemId = "systemId2"
};
await IntegrationDb.Database.DropCollectionAsync("patients_alarms");
await IntegrationDb.Database.CreateCollectionAsync("patients_alarms");
_logger = new Mock<ILogger<AlarmRepository>>();
_repository = new AlarmRepository(_optionsApiSettings, IntegrationDb.Database, _logger.Object);
await _repository.InsertOneAsync(pObsAlarm1);
await _repository.InsertOneAsync(pObsAlarm2);
}
private AlarmRepository _repository;
private readonly ApiSettings _apiSettings = new()
{
PatientsAlarms = "patients_alarms"
};
private IOptions<ApiSettings>? _optionsApiSettings;
private Mock<ILogger<AlarmRepository>> _logger;
private static readonly DateTime Now = DateTime.UtcNow;
private static readonly ObjectId PatientId = ObjectId.GenerateNewId();
private static readonly ObjectId Id = ObjectId.GenerateNewId();
/// <summary>
/// Verifies that <see cref="AlarmRepository.AggregatedPatientLastObservationsByField"/> returns an empty list when no observations match the provided field filter criteria.
/// </summary>
/// <param name="filter">The collection of <see cref="Field"/> objects used to filter observations; contains a single non-existent field to ensure no matches are found.</param>
/// <returns>A task that completes after asserting the repository returns a non-null but empty result.</returns>
/// <!-- aidoc-review:v1 severity=medium kind=extra_param
/// "The test method has no parameters, but the documentation includes a <param name=\"filter\"> describing the local variable rather than a method parameter." -->
[Test]
public async Task AggregatedPatientLastObservationsByField_Not_Found_Returns_Empty_List()
{
var filter = new List<Field>
{
new()
{
Name = "name100",
Last = 2,
OnlyExpired = false
}
};
var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, filter);
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.Empty);
}
/// <summary>
/// Verifies that AggregatedPatientLastObservationsByField returns exactly one aggregated result when matching last observations are found for the specified patient and field filter.
/// </summary>
/// <!-- aidoc:v1 sig=9bbf1e0 body=05c8194 -->
[Test]
public async Task AggregatedPatientLastObservationsByField_Found_Returns_1()
{
var filter = new List<Field>
{
new()
{
Name = "name1",
Last = 2,
OnlyExpired = false
}
};
var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, filter);
Assert.That(result, Is.Not.Null);
Assert.That(result.Count(), Is.EqualTo(1));
}
/// <summary>
/// Verifies that <see cref="AlarmRepository.AggregatedPatientLastObservationsByField"/> returns a non-null collection containing an entry for each matching field in the filter when observations are found for the given patient.
/// </summary>
/// <!-- aidoc:v1 sig=7bd117f body=144c5f6 -->
[Test]
public async Task AggregatedPatientLastObservationsByField_Found_Returns_2()
{
var filter = new List<Field>
{
new()
{
Name = "name1",
Last = 1,
OnlyExpired = false
},
new()
{
Name = "name2",
Last = 1,
OnlyExpired = false
}
};
var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, filter);
Assert.That(result, Is.Not.Null);
Assert.That(result.Count(), Is.EqualTo(2));
}
/// <summary>
/// Verifies that the repository returns an empty list when querying aggregated patient last observations by field with a filter that specifies OnlyExpired as true, and the matching patient observation alarm is expired.
/// </summary>
/// <!-- aidoc:v1 sig=80c2dcc body=92a6f2f -->
[Test]
public async Task AggregatedPatientLastObservationsByField_AllExpired_Returns_Empty_List()
{
var expiredTime = Now.AddDays(-1); // Set a time in the past to simulate expiration
var expiredObs = new PatientObservationAlarm
{
Id = ObjectId.GenerateNewId(),
PatientId = PatientId,
Code = "code3",
CodingSystem = "SNM",
Name = "name3",
Time = expiredTime,
Value = "value3",
SystemId = "systemId3",
Expired = true
};
await _repository.InsertOneAsync(expiredObs);
var filter = new List<Field>
{
new()
{
Name = "name3",
Last = 2,
OnlyExpired = true
}
};
var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, filter);
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.Empty);
}
/// <summary>
/// Verifies that when multiple observations exist for the same field, the aggregation returns only the most recent observation based on the timestamp.
/// </summary>
/// <!-- aidoc:v1 sig=36c9e3d body=9fe0818 -->
[Test]
public async Task AggregatedPatientLastObservationsByField_MultipleObservations_Returns_Most_Recent()
{
var oldTime = Now.AddMinutes(-10); // Set an older time
var oldObs = new PatientObservationAlarm
{
Id = ObjectId.GenerateNewId(),
PatientId = PatientId,
Code = "code4",
CodingSystem = "SNM",
Name = "name4",
Time = oldTime,
Value = "value4",
SystemId = "systemId4"
};
var newObs = new PatientObservationAlarm
{
Id = ObjectId.GenerateNewId(),
PatientId = PatientId,
Code = "code4",
CodingSystem = "SNM",
Name = "name4",
Time = Now,
Value = "value5",
SystemId = "systemId5"
};
await _repository.InsertOneAsync(oldObs);
await _repository.InsertOneAsync(newObs);
var filter = new List<Field>
{
new()
{
Name = "name4",
Last = 1,
OnlyExpired = false
}
};
var result = await _repository.AggregatedPatientLastObservationsByField(PatientId, filter);
Assert.That(result, Is.Not.Null);
using (Assert.EnterMultipleScope())
{
Assert.That(result, Has.Count.EqualTo(1));
Assert.That(result.First().Value, Is.EqualTo("value5")); // Ensure the most recent observation is returned
};
}
/// <summary>
/// Verifies that <see cref="AlarmRepository.AggregatedPatientLastObservationsByField"/> returns all of a patient's last observations when no field filter is provided.
/// </summary>
/// <!-- aidoc:v1 sig=621b9bb body=6fff436 -->
[Test]
public async Task AggregatedPatientLastObservationsByField_FilterObservations_Null_Returns_All()
{
var result = await _repository.AggregatedPatientLastObservationsByField(PatientId);
Assert.That(result, Is.Not.Null);
Assert.That(result, Is.Not.Empty); // Ensure it returns all observations for the patient
}
}