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

396 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using adas_core.Domain.Enums;
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;
namespace adas_core.Test.Repositories;
[TestFixture]
[Category("Integration")]
public class PumpAlarmEventRepositoryTest
{
private PumpAlarmEventRepository _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 Setup inicial de colección con índices y datos de prueba
// -------------------------------------------------------------------
[OneTimeSetUp]
public async Task Init()
{
_apiSettings = Options.Create(new ApiSettings
{
PumpAlarmEvent = "pump_alarm_event"
});
await IntegrationDb.Database.DropCollectionAsync("pump_alarm_event");
await IntegrationDb.Database.CreateCollectionAsync("pump_alarm_event");
_repo = new PumpAlarmEventRepository(
_apiSettings,
IntegrationDb.Database
);
await _repo.CreateIndexes();
var initialEvents = new List<PumpAlarmEvent>
{
new()
{
Id = ObjectId.GenerateNewId(),
DeviceId = DeviceA,
PatientId = PatientId,
AlarmType = PumpEnum.AlarmType.Attention,
Time = Now.AddSeconds(-1)
},
new()
{
Id = ObjectId.GenerateNewId(),
DeviceId = DeviceA,
PatientId = PatientId,
AlarmType = PumpEnum.AlarmType.Occlusion,
Time = Now.AddSeconds(-3)
},
new()
{
Id = ObjectId.GenerateNewId(),
DeviceId = DeviceB,
PatientId = PatientId,
AlarmType = PumpEnum.AlarmType.Occlusion,
Time = Now.AddSeconds(-2)
}
};
await IntegrationDb.Database
.GetCollection<PumpAlarmEvent>("pump_alarm_event")
.InsertManyAsync(initialEvents);
var count = await _repo.Collection.CountDocumentsAsync(_ => true);
Assert.That(count, Is.EqualTo(3));
}
// -------------------------------------------------------------------
// INSERT
// -------------------------------------------------------------------
[Test]
public async Task InsertAsync_Works()
{
var evt = new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-C",
PatientId = PatientId,
AlarmType = PumpEnum.AlarmType.Occlusion,
Time = Now
};
await _repo.InsertAsync(evt);
var found = await _repo.Collection.FindAsync(x => x.Id == evt.Id);
Assert.That(found.FirstOrDefault(), Is.Not.Null);
}
// -------------------------------------------------------------------
// FIND BY DEVICE ID
// -------------------------------------------------------------------
[Test]
public async Task FindByDeviceIdAsync_ReturnsOrdered()
{
var result = await _repo.FindByDeviceIdAsync(DeviceA);
var list = result.ToList();
using (Assert.EnterMultipleScope())
{
Assert.That(list, Is.Not.Empty);
Assert.That(list.First().Time, Is.GreaterThanOrEqualTo(list.Last().Time));
}
}
[Test]
public async Task FindByDeviceIdAsync_WithDateRange_Works()
{
var from = Now.AddSeconds(-2);
var to = Now;
var result = await _repo.FindByDeviceIdAsync(DeviceA, from, to);
using (Assert.EnterMultipleScope())
{
var pumpAlarmEvents = result.ToList();
Assert.That(pumpAlarmEvents, Is.Not.Empty);
Assert.That(pumpAlarmEvents.All(x => x.Time >= from && x.Time <= to), Is.True);
}
}
[Test]
public async Task FindByDeviceIdAsync_WithLimit_Works()
{
var result = await _repo.FindByDeviceIdAsync(DeviceA, limit: 1);
var list = result.ToList();
Assert.That(list, Has.Count.EqualTo(1));
}
// -------------------------------------------------------------------
// FIND LAST BY DEVICE
// -------------------------------------------------------------------
[Test]
public async Task FindLastByDeviceIdAsync_Works()
{
// Arrange: dataset ya insertado en Init()
var events = await _repo.FindByDeviceIdAsync("Device-A");
var expected = events.OrderByDescending(e => e.Time).First();
// Act
var evt = await _repo.FindLastByDeviceIdAsync("Device-A");
// Assert
Assert.That(evt, Is.Not.Null);
Assert.That(evt!.Id, Is.EqualTo(expected.Id)); // comparación robusta
}
// -------------------------------------------------------------------
// DELETE BY PATIENT ID
// -------------------------------------------------------------------
[Test]
public async Task DeleteByPatientId_Works()
{
var patient2 = ObjectId.GenerateNewId();
var evt = new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-X",
PatientId = patient2,
AlarmType = PumpEnum.AlarmType.Occlusion,
Time = Now
};
await _repo.InsertAsync(evt);
await _repo.DeleteByPatientId(patient2);
var found = await _repo.Collection.FindAsync(x => x.PatientId == patient2);
Assert.That(await found.AnyAsync(), Is.False);
}
// -------------------------------------------------------------------
// UPDATE MANY (CAMBIO DE PATIENTID O SIMILAR)
// -------------------------------------------------------------------
[Test]
public async Task UpdateManyObjectIdByFiledNameAsync_Works()
{
var oldId = ObjectId.GenerateNewId();
var newId = ObjectId.GenerateNewId();
var evt = new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-U",
PatientId = oldId,
AlarmType = PumpEnum.AlarmType.Attention,
Time = Now
};
await _repo.InsertAsync(evt);
var updated = await _repo.UpdateManyObjectIdByFiledNameAsync("PatientId", newId, oldId);
Assert.That(updated, Is.EqualTo(1));
var found = await _repo.Collection.FindAsync(x => x.PatientId == newId);
Assert.That(await found.AnyAsync(), Is.True);
}
[Test]
public async Task FindByDeviceIdAsync_ReturnsEmpty_WhenOutOfRange()
{
var from = Now.AddYears(-2);
var to = Now.AddYears(-2).AddDays(1);
var result = await _repo.FindByDeviceIdAsync("Device-A", from, to);
Assert.That(result, Is.Empty);
}
[Test]
public async Task FindByDeviceIdAsync_RespectsLimitAndOrder()
{
// Semilla adicional para asegurar > 1
var events = new[]
{
new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = DeviceA, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.AirInLine, Time = Now.AddMilliseconds(-10) },
new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = DeviceA, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.Occlusion, Time = Now.AddMilliseconds(-5) }
};
await _repo.Collection.InsertManyAsync(events);
var result = await _repo.FindByDeviceIdAsync(DeviceA, limit: 1);
var list = result.ToList();
using (Assert.EnterMultipleScope())
{
Assert.That(list, Has.Count.EqualTo(1));
var last = await _repo.FindLastByDeviceIdAsync(DeviceA);
Assert.That(list[0].Id, Is.EqualTo(last!.Id));
}
}
[Test]
public async Task InsertAsync_AllowsNullOptionalFields()
{
var evt = new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-Nulls",
PatientId = null, // opcional
AlarmType = null, // opcional
Time = Now
};
await _repo.InsertAsync(evt);
var found = await _repo.Collection.FindAsync(x => x.Id == evt.Id);
Assert.That(found.FirstOrDefault(), Is.Not.Null);
}
[Test]
public async Task DeleteByPatientId_DeletesMany_AndIsIdempotent()
{
var pid = ObjectId.GenerateNewId();
var docs = Enumerable.Range(0, 3).Select(i => new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-Del",
PatientId = pid,
AlarmType = PumpEnum.AlarmType.Attention,
Time = Now.AddSeconds(-i)
});
await _repo.Collection.InsertManyAsync(docs);
// Primera vez: borra 3
await _repo.DeleteByPatientId(pid);
var left = await _repo.Collection.FindAsync(x => x.PatientId == pid);
Assert.That(left.ToList(), Is.Empty);
Func<Task> act = async () => await _repo.DeleteByPatientId(pid);
Assert.That(act, Throws.Nothing);
}
[Test]
public async Task UpdateManyObjectIdByFiledNameAsync_UpdatesMultiple()
{
var oldId = ObjectId.GenerateNewId();
var newId = ObjectId.GenerateNewId();
var events = Enumerable.Range(0, 4).Select(i => new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-U",
PatientId = oldId,
AlarmType = PumpEnum.AlarmType.AirInLine,
Time = Now.AddMilliseconds(-i)
});
await _repo.Collection.InsertManyAsync(events);
var modified = await _repo.UpdateManyObjectIdByFiledNameAsync("PatientId", newId, oldId);
using (Assert.EnterMultipleScope())
{
Assert.That(modified, Is.EqualTo(4));
var foundNew = await _repo.Collection.FindAsync(x => x.PatientId == newId);
Assert.That(foundNew.ToList(), Has.Count.EqualTo(4));
}
}
[Test]
public async Task FindByDeviceIdAsync_InclusiveRange_BoundsRespected()
{
var start = Now.AddMinutes(-30);
var end = Now.AddMinutes(-29);
var exactEvt = new PumpAlarmEvent
{
Id = ObjectId.GenerateNewId(),
DeviceId = "Device-Range",
PatientId = PatientId,
AlarmType = PumpEnum.AlarmType.Attention,
Time = end // exactamente igual al to
};
await _repo.InsertAsync(exactEvt);
var result = await _repo.FindByDeviceIdAsync("Device-Range", from: start, to: end);
using (Assert.EnterMultipleScope())
{
var pumpAlarmEvents = result as PumpAlarmEvent[] ?? result.ToArray();
Assert.That(pumpAlarmEvents, Is.Not.Empty);
Assert.That(pumpAlarmEvents.All(r => r.Time >= start && r.Time <= end), Is.True);
}
}
[Test]
public async Task FindLastByDeviceIdAsync_TracksNewest()
{
const string dev = "Device-LastCheck";
var e1 = new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = dev, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.AirInLine, Time = Now.AddSeconds(-10) };
var e2 = new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = dev, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.Occlusion, Time = Now.AddSeconds(-5) };
await _repo.Collection.InsertManyAsync([e1, e2]);
var last1 = await _repo.FindLastByDeviceIdAsync(dev);
Assert.That(last1!.Id, Is.EqualTo(e2.Id));
var e3 = new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = dev, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.Attention, Time = Now };
await _repo.InsertAsync(e3);
var last2 = await _repo.FindLastByDeviceIdAsync(dev);
Assert.That(last2!.Id, Is.EqualTo(e3.Id));
}
[Test]
public async Task FindByDeviceIdAsync_MultipleOverlappingRanges()
{
const string dev = "Device-Timeline";
var batch = new[]
{
new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = dev, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.AirInLine, Time = Now.AddMinutes(-20) },
new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = dev, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.Occlusion, Time = Now.AddMinutes(-10) },
new PumpAlarmEvent { Id = ObjectId.GenerateNewId(), DeviceId = dev, PatientId = PatientId, AlarmType = PumpEnum.AlarmType.Attention, Time = Now.AddMinutes(-5) }
};
await _repo.Collection.InsertManyAsync(batch);
var r1 = await _repo.FindByDeviceIdAsync(dev, from: Now.AddMinutes(-30), to: Now.AddMinutes(-15));
var r2 = await _repo.FindByDeviceIdAsync(dev, from: Now.AddMinutes(-12), to: Now.AddMinutes(-8));
var r3 = await _repo.FindByDeviceIdAsync(dev, from: Now.AddMinutes(-6), to: Now);
using (Assert.EnterMultipleScope())
{
var r1List = r1.ToList();
Assert.That(r1List, Has.Count.EqualTo(1)); // -20
var r2List = r2.ToList();
Assert.That(r2List, Has.Count.EqualTo(1)); // -10
var r3List = r3.ToList();
Assert.That(r3List, Has.Count.EqualTo(1)); // -5
}
}
}