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; 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 // ============================================================ [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 { 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("pump_states") .InsertManyAsync(initialStates); var count = await _repo.Collection.CountDocumentsAsync(_ => true); Assert.That(count, Is.EqualTo(2)); } // ============================================================ // FIND BY DEVICE ID // ============================================================ [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) // ============================================================ [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); } [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 // ============================================================ [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) // ============================================================ [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)); } }