Files
adas-core/adas-core.Test/Repositories/PumpStateRepositoryTest.cs
T
2026-06-26 10:29:23 +02:00

207 lines
7.4 KiB
C#

using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Pumps;
using adas_core.Infrastructure.Repositories;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using adas_core.Domain.Enums;
namespace adas_core.Test.Repositories;
[TestFixture]
[Category("Integration")]
public class PumpStateRepositoryTest
{
private PumpStateRepository _repo;
private IOptions<ApiSettings> _apiSettings;
private static readonly DateTime Now = DateTime.UtcNow;
private const string DeviceA = "Device-A";
private const string DeviceB = "Device-B";
private static readonly ObjectId PatientId = ObjectId.GenerateNewId();
// ============================================================
// INIT
// ============================================================
/// <summary>
/// One-time setup that prepares the integration test environment for the PumpStateRepository by recreating the
/// "pump_states" MongoDB collection, building the repository indexes, and seeding two initial pump states (one
/// actively infusing for a known patient/device and one not infusing) to verify the baseline document count.
/// </summary>
[OneTimeSetUp]
public async Task Init()
{
_apiSettings = Options.Create(new ApiSettings
{
PumpStates = "pump_states"
});
await IntegrationDb.Database.DropCollectionAsync("pump_states");
await IntegrationDb.Database.CreateCollectionAsync("pump_states");
_repo = new PumpStateRepository(
_apiSettings,
IntegrationDb.Database
);
await _repo.CreateIndexes();
// Insertar estados iniciales
var initialStates = new List<PumpState>
{
new()
{
Id = ObjectId.GenerateNewId(),
DeviceId = DeviceA,
PatientId = PatientId,
LastUpdated = Now,
IsInfusing = true,
Status = PumpEnum.Status.Infusing,
PumpMode = PumpEnum.Mode.Infusing
},
new()
{
Id = ObjectId.GenerateNewId(),
DeviceId = DeviceB,
LastUpdated = Now.AddSeconds(-10),
IsInfusing = false,
Status = PumpEnum.Status.NotInfusing
}
};
await IntegrationDb.Database.GetCollection<PumpState>("pump_states")
.InsertManyAsync(initialStates);
var count = await _repo.Collection.CountDocumentsAsync(_ => true);
Assert.That(count, Is.EqualTo(2));
}
// ============================================================
// FIND BY DEVICE ID
// ============================================================
/// <summary>
/// Verifies that FindByDeviceIdAsync retrieves the correct infusion state for a given device, returning a non-null result that matches the requested device identifier and reflects the expected infusion status.
/// </summary>
[Test]
public async Task FindByDeviceIdAsync_ReturnsCorrectState()
{
var state = await _repo.FindByDeviceIdAsync(DeviceA);
Assert.That(state, Is.Not.Null);
using (Assert.EnterMultipleScope())
{
Assert.That(state!.DeviceId, Is.EqualTo(DeviceA));
Assert.That(state.IsInfusing, Is.True);
}
}
// ============================================================
// UPSERT (INSERT + UPDATE)
// ============================================================
/// <summary>
/// Verifies that <c>UpsertAsync</c> inserts a new <see cref="PumpState"/> record when no existing entry is found for the specified <c>DeviceId</c>, and that the persisted state retains the provided property values.
/// </summary>
[Test]
public async Task UpsertAsync_InsertsNewWhenNotExists()
{
var newState = new PumpState
{
DeviceId = "Device-C",
PatientId = ObjectId.GenerateNewId(),
LastUpdated = Now,
IsInfusing = false
};
await _repo.UpsertAsync(newState);
var found = await _repo.FindByDeviceIdAsync("Device-C");
Assert.That(found, Is.Not.Null);
Assert.That(found!.IsInfusing, Is.False);
}
/// <summary>
/// Verifies that <c>UpsertAsync</c> correctly updates an existing pump state in the repository, ensuring
/// the updated <see cref="PumpState"/> is persisted and retrievable with the modified <c>IsInfusing</c>,
/// <c>Status</c>, and <c>LastUpdated</c> values.
/// </summary>
[Test]
public async Task UpsertAsync_UpdatesExistingState()
{
var updated = new PumpState
{
DeviceId = DeviceA,
PatientId = PatientId,
LastUpdated = Now.AddMinutes(1),
IsInfusing = false,
Status = PumpEnum.Status.NotInfusing
};
await _repo.UpsertAsync(updated);
var found = await _repo.FindByDeviceIdAsync(DeviceA);
Assert.That(found, Is.Not.Null);
using (Assert.EnterMultipleScope())
{
Assert.That(found!.IsInfusing, Is.False);
Assert.That(found.Status, Is.EqualTo(PumpEnum.Status.NotInfusing));
Assert.That(
found.LastUpdated,
Is.EqualTo(updated.LastUpdated).Within(TimeSpan.FromMilliseconds(1))
);
}
}
// ============================================================
// GET ALL
// ============================================================
/// <summary>
/// Verifies that <c>GetAllAsync</c> returns a non-null collection of pump states containing at least two entries, including those associated with the seeded devices A and B.
/// </summary>
[Test]
public async Task GetAllAsync_ReturnsAllStates()
{
var list = await _repo.GetAllAsync();
var pumpStates = list.ToList();
Assert.That(pumpStates, Is.Not.Null);
Assert.That(pumpStates, Has.Count.GreaterThanOrEqualTo(2));
var containsA = pumpStates.Any(x => x.DeviceId == DeviceA);
var containsB = pumpStates.Any(x => x.DeviceId == DeviceB);
using (Assert.EnterMultipleScope())
{
Assert.That(containsA, Is.True);
Assert.That(containsB, Is.True);
}
}
// ============================================================
// UNIQUE INDEX: UPSERT OVERWRITES (NO DUPLICADOS)
// ============================================================
/// <summary>
/// Verifies that UpsertAsync updates an existing entity instead of inserting a duplicate, ensuring the total record count remains unchanged when upserting a <see cref="PumpState"/> for an already-known device identifier.
/// </summary>
[Test]
public async Task UpsertAsync_DoesNotCreateDuplicates()
{
var before = await _repo.GetAllAsync();
var countBefore = before.Count();
// Insert (upsert) for existing DeviceA
var state = new PumpState
{
DeviceId = DeviceA,
LastUpdated = Now.AddMinutes(5)
};
await _repo.UpsertAsync(state);
var after = await _repo.GetAllAsync();
var countAfter = after.Count();
// No debe aumentar, porque es un update, no un insert
Assert.That(countAfter, Is.EqualTo(countBefore));
}
}