Creado apartir del commit b888de6c92056de294456f581a56e25e734d4ab7 de develop

This commit is contained in:
jrojas
2026-06-26 09:52:35 +02:00
commit 319fd3dfb0
746 changed files with 106610 additions and 0 deletions
@@ -0,0 +1,634 @@
using adas_core.Application.Services.Caching;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Utils;
using MongoDB.Bson;
using Moq;
using Microsoft.Extensions.Logging;
namespace adas_core.Test.Utilities;
[TestFixture]
public class CacheKeyClassifierTest
{
#region TC-01
[Test]
public void Classify_ReturnsPatients_ForKeyStartingWithPatients()
{
// Arrange
var key = "patients:latestObs:abc123:HR:0";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Patients));
}
[Test]
public void Classify_ReturnsPatients_ForKeyStartingWithPatientsXYZ()
{
// Arrange
var key = "patients:xyz:any:key";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Patients));
}
#endregion
#region TC-02
[Test]
public void Classify_ReturnsDisplays_ForKeyStartingWithConfigDisplaysBase()
{
// Arrange
//var key2 = "configDisplays:display:id:base";
var key = "configDisplays:display:690b341c4a349b5898898241:base ";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Displays));
}
[Test]
public void Classify_ReturnsDisplays_ForKeyStartingWithConfigDisplaysConfig()
{
// Arrange
var key = "configDisplays:display:id:config";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Displays));
}
#endregion
#region TC-03
[Test]
public void Classify_ReturnsPumpObservations_ForKeyStartingWithPumpObs()
{
// Arrange
var key = "pumpObs:latest:patientId:10";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.PumpObservations));
}
#endregion
#region TC-04
[Test]
public void Classify_ReturnsAppointments_ForKeyStartingWithAppointmentsPatient()
{
// Arrange
var key = "appointments:patient:id:20260224";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Appointments));
}
[Test]
public void Classify_ReturnsAppointments_ForKeyStartingWithAppointmentsPoc()
{
// Arrange
var key = "appointments:PoC:pocId:20260224";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Appointments));
}
#endregion
#region TC-05
[Test]
public void Classify_ReturnsGroupedObservations_ForKeyStartingWithGroupedObs()
{
// Arrange
var key = "groupedObs:HR:patient:abc123";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.GroupedObservations));
}
#endregion
#region TC-06
[Test]
public void Classify_ReturnsConfigObservations_ForKeyStartingWithConfigObservations()
{
// Arrange
var key = "configObservations:all";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.ConfigObservations));
}
#endregion
#region TC-07
[Test]
public void Classify_ReturnsUnknown_ForUnrecognizedPrefixDiagnostics()
{
// Arrange
var key = "diagnostics:patient:abc";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Unknown));
}
[Test]
public void Classify_ReturnsUnknown_ForUnrecognizedPrefixRandom()
{
// Arrange
var key = "random:key";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Unknown));
}
#endregion
#region TC-08
[Test]
public void Classify_ReturnsPatients_ForKeyInUpperCase()
{
// Arrange
var key = "PATIENTS:latestObs:abc";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Patients));
}
[Test]
public void Classify_ReturnsAppointments_ForKeyInMixedCase()
{
// Arrange
var key = "Appointments:PoC:id:date";
// Act
var result = CacheKeyClassifier.Classify(key);
// Assert
Assert.That(result, Is.EqualTo(CacheEnum.EntityType.Appointments));
}
#endregion
#region TC-09
[Test]
public void ResolveForEntity_ReturnsNull_WhenGlobalCacheDisabled()
{
// Arrange
var settings = new CacheSettings
{
IsEnabled = false,
Patients = CacheEnum.Mode.Redis,
Redis = new RedisSettings
{
Ttl = new TtlSettings { PatientsSeconds = 600 }
}
};
// Act
var result = CacheKeyTtl.ResolveForEntity(settings, CacheEnum.EntityType.Patients);
// Assert
Assert.That(result, Is.Null);
}
[Test]
public void ResolveForEntity_ReturnsNull_WhenGlobalDisabled_ForAllEntities()
{
// Arrange
var entities = new[]
{
CacheEnum.EntityType.Patients,
CacheEnum.EntityType.Displays,
CacheEnum.EntityType.PumpObservations,
CacheEnum.EntityType.Appointments,
CacheEnum.EntityType.PontOfCare,
CacheEnum.EntityType.GroupedObservations,
CacheEnum.EntityType.PatientObservations,
CacheEnum.EntityType.ConfigObservations
};
var settings = new CacheSettings { IsEnabled = false };
// Act & Assert
foreach (var entity in entities)
{
var result = CacheKeyTtl.ResolveForEntity(settings, entity);
Assert.That(result, Is.Null, $"Expected null for entity {entity}");
}
}
#endregion
#region TC-10
[Test]
public void ResolveForEntity_ReturnsNull_WhenEntityModeIsNone()
{
// Arrange
var settings = new CacheSettings
{
IsEnabled = true,
PumpObservations = CacheEnum.Mode.None,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings { PumpObservationsSeconds = 300 }
}
};
// Act
var result = CacheKeyTtl.ResolveForEntity(settings, CacheEnum.EntityType.PumpObservations);
// Assert
Assert.That(result, Is.Null);
}
#endregion
#region TC-11
[Test]
public void ResolveForEntity_UsesEntitySpecificTtl_WhenModeIsCache()
{
// Arrange
var settings = new CacheSettings
{
IsEnabled = true,
Patients = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings
{
GlobalSeconds = 3600,
PatientsSeconds = 600
}
}
};
// Act
var result = CacheKeyTtl.ResolveForEntity(settings, CacheEnum.EntityType.Patients);
// Assert
Assert.That(result, Is.EqualTo(TimeSpan.FromSeconds(600)));
Assert.That(result, Is.Not.EqualTo(TimeSpan.FromSeconds(3600)));
}
#endregion
#region TC-12
[Test]
public void ResolveForEntity_UsesRedisTtl_WhenModeIsRedis()
{
// Arrange
var settings = new CacheSettings
{
IsEnabled = true,
Appointments = CacheEnum.Mode.Redis,
Redis = new RedisSettings
{
Ttl = new TtlSettings
{
GlobalSeconds = 3600,
AppointmentsSeconds = 900
}
}
};
// Act
var result = CacheKeyTtl.ResolveForEntity(settings, CacheEnum.EntityType.Appointments);
// Assert
Assert.That(result, Is.EqualTo(TimeSpan.FromSeconds(900)));
}
#endregion
#region TC-13
[Test]
public void ResolveForEntity_UsesGlobalSeconds_WhenNoEntitySpecificTtl()
{
// Arrange
var settings = new CacheSettings
{
IsEnabled = true,
Patients = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings
{
GlobalSeconds = 3600
// No PatientsSeconds defined
}
}
};
// Act
var result = CacheKeyTtl.ResolveForEntity(settings, CacheEnum.EntityType.Patients);
// Assert
Assert.That(result, Is.EqualTo(TimeSpan.FromSeconds(3600)));
}
#endregion
#region TC-14
[Test]
public void ResolveForEntity_ReturnsNull_WhenNoTtlConfigured()
{
// Arrange
var settings = new CacheSettings
{
IsEnabled = true,
Patients = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings()
// No GlobalSeconds, no PatientsSeconds
}
};
// Act
var result = CacheKeyTtl.ResolveForEntity(settings, CacheEnum.EntityType.Patients);
// Assert
Assert.That(result, Is.Null);
}
#endregion
#region TC-15
[Test]
public void PatientAppointmentsTodayKeyWithTtl_GeneratesCorrectFormat()
{
// Arrange
var patientId = ObjectId.GenerateNewId();
var today = DateTime.UtcNow.ToString("yyyyMMdd");
var settings = new CacheSettings
{
IsEnabled = true,
Appointments = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings { AppointmentsSeconds = 120 }
}
};
// Act
var (key, ttl) = CacheKeys.PatientAppointmentsTodayKeyWithTtl(settings, patientId);
// Assert
Assert.That(key, Is.EqualTo($"appointments:patient:{patientId}:{today}"));
Assert.That(ttl, Is.EqualTo(TimeSpan.FromSeconds(120)));
}
#endregion
#region TC-16
[Test]
public void PocAppointmentsTodayKeyWithTtl_GeneratesCorrectFormat()
{
// Arrange
var pocId = ObjectId.GenerateNewId();
var today = DateTime.UtcNow.ToString("yyyyMMdd");
var settings = new CacheSettings
{
IsEnabled = true,
PointOfCares = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings { PointOfCaresSeconds = 180 }
}
};
// Act
var (key, ttl) = CacheKeys.PocAppointmentsTodayKeyWithTtl(settings, pocId);
// Assert
Assert.That(key, Is.EqualTo($"appointments:PoC:{pocId}:{today}"));
Assert.That(ttl, Is.EqualTo(TimeSpan.FromSeconds(180)));
}
#endregion
#region TC-17
[Test]
public void LatestObservationsKeyWithTtl_SortsFieldNamesAlphabetically()
{
// Arrange
var patientId = ObjectId.GenerateNewId();
var settings = new CacheSettings();
// Act
var (key1, _) = CacheKeys.LatestObservationsKeyWithTtl(
settings, patientId, new[] { "Systolic", "HR", "Diastolic" });
var (key2, _) = CacheKeys.LatestObservationsKeyWithTtl(
settings, patientId, new[] { "HR", "Diastolic", "Systolic" });
// Assert
Assert.That(key1, Is.EqualTo(key2));
Assert.That(key1, Does.Contain("Diastolic|HR|Systolic"));
}
#endregion
#region TC-18
[Test]
public void LatestObservationsKeyWithTtl_ExcludesEmptyFields()
{
// Arrange
var patientId = ObjectId.GenerateNewId();
var settings = new CacheSettings();
// Act
var (key, _) = CacheKeys.LatestObservationsKeyWithTtl(
settings, patientId, new[] { "HR", "", "Diastolic", null! });
// Assert
Assert.That(key.Contains("||"), Is.False);
Assert.That(key, Does.Contain("Diastolic|HR"));
}
#endregion
#region TC-19
[Test]
public void DisplayBaseKeyWithTtl_GeneratesCorrectFormat()
{
// Arrange
var displayId = ObjectId.GenerateNewId();
var settings = new CacheSettings
{
IsEnabled = true,
Displays = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings { DisplaysSeconds = 300 }
}
};
// Act
var (key, ttl) = CacheKeys.DisplayBaseKeyWithTtl(settings, displayId);
// Assert
Assert.That(key, Is.EqualTo($"configDisplays:display:{displayId}:base"));
Assert.That(ttl, Is.EqualTo(TimeSpan.FromSeconds(300)));
}
#endregion
#region TC-20
[Test]
public void DisplayWithConfigKeyWithTtl_GeneratesCorrectFormat()
{
// Arrange
var displayId = ObjectId.GenerateNewId();
var settings = new CacheSettings();
// Act
var (keyBase, _) = CacheKeys.DisplayBaseKeyWithTtl(settings, displayId);
var (keyConfig, _) = CacheKeys.DisplayWithConfigKeyWithTtl(settings, displayId);
// Assert
Assert.That(keyConfig, Is.EqualTo($"configDisplays:display:{displayId}:config"));
Assert.That(keyBase, Is.Not.EqualTo(keyConfig));
}
#endregion
#region TC-21
[Test]
public void PointOfCareBaseKeyWithTtl_GeneratesCorrectFormat()
{
// Arrange
var pocId = ObjectId.GenerateNewId();
var settings = new CacheSettings
{
IsEnabled = true,
PointOfCares = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings { PointOfCaresSeconds = 240 }
}
};
// Act
var (key, ttl) = CacheKeys.PointOfCareBaseKeyWithTtl(settings, pocId);
// Assert
Assert.That(key, Is.EqualTo($"pointOfCare:{pocId}:base"));
Assert.That(ttl, Is.EqualTo(TimeSpan.FromSeconds(240)));
}
#endregion
#region TC-22
[Test]
public void ConfigObservationsAllKeyWithTtl_GeneratesCorrectFormat()
{
// Arrange
var settings1 = new CacheSettings();
var settings2 = new CacheSettings
{
IsEnabled = true,
ConfigObservations = CacheEnum.Mode.Cache,
InMemory = new InMemorySettings
{
Ttl = new TtlSettings { ConfigObservationsSeconds = 600 }
}
};
// Act
var (key1, _) = CacheKeys.ConfigObservationsAllKeyWithTtl(settings1);
var (key2, _) = CacheKeys.ConfigObservationsAllKeyWithTtl(settings2);
// Assert
Assert.That(key1, Is.EqualTo("configObservations:all"));
Assert.That(key2, Is.EqualTo("configObservations:all"));
Assert.That(key1, Is.EqualTo(key2));
}
#endregion
#region TC-59
[TestCase(CacheEnum.EntityType.Patients, "patients:*")]
[TestCase(CacheEnum.EntityType.Displays, "displays:*")]
[TestCase(CacheEnum.EntityType.PumpObservations, "pumpObs:*")]
[TestCase(CacheEnum.EntityType.Appointments, "appointments:*")]
[TestCase(CacheEnum.EntityType.GroupedObservations, "groupedObs:*")]
[TestCase(CacheEnum.EntityType.ConfigObservations, "configObservation:*")]
[TestCase(CacheEnum.EntityType.Unknown, "*")]
public void ForEntity_ReturnsCorrectPatternForEachEntityType(
CacheEnum.EntityType entity, string expectedPattern)
{
var result = CacheKeyPatterns.ForEntity(entity);
Assert.That(result, Is.EqualTo(expectedPattern));
}
#endregion
#region TC-60
[Test]
public void ByPatient_ReturnsPatternContainingPrefixAndPatientId()
{
const string prefix = "patients:latestObs";
const string patientId = "abc123";
var pattern = CacheKeyPatterns.ByPatient(prefix, patientId);
Assert.That(pattern, Is.EqualTo($"{prefix}:*:{patientId}*"));
Assert.That(pattern, Does.Contain(prefix));
Assert.That(pattern, Does.Contain(patientId));
}
[Test]
public async Task ByPatient_DeleteByPatternAsync_OnlyRemovesMatchingPatientKeys()
{
var lockMgr = new LockManagerService(
new Mock<ILogger<LockManagerService>>().Object,
new InMemoryLockProvider());
var svc = new CacheService(lockMgr);
const string prefix = "patients:latestObs";
const string patientId = "abc123";
const string otherId = "def456";
var pattern = CacheKeyPatterns.ByPatient(prefix, patientId);
var effectiveSubstring = pattern.Replace("*", "");
var matchingKey = $"{effectiveSubstring}:HR:0";
var nonMatchingKey = $"patients:latestObs::{otherId}:HR:0";
var differentEntityKey = $"appointments::{patientId}:data";
await svc.SetObjectAsync(matchingKey, "val1");
await svc.SetObjectAsync(nonMatchingKey, "val2");
await svc.SetObjectAsync(differentEntityKey, "val3");
var deleted = await svc.DeleteByPatternAsync(pattern);
Assert.That(deleted, Is.EqualTo(1));
Assert.That(await svc.GetObjectAsync<string>(matchingKey), Is.Null);
Assert.That(await svc.GetObjectAsync<string>(nonMatchingKey), Is.EqualTo("val2"));
Assert.That(await svc.GetObjectAsync<string>(differentEntityKey), Is.EqualTo("val3"));
}
#endregion
}
+263
View File
@@ -0,0 +1,263 @@
using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.GroupedObservations;
using adas_core.Domain.Models.Masters;
using adas_core.Domain.Models.MongoModels;
using MongoDB.Bson;
namespace adas_core.Test.Utilities;
public class TestUtilities
{
public static PointOfCare CreateValidPointOfCare()
{
return new PointOfCare
{
Id = ObjectId.GenerateNewId(),
Room = "Test Room",
Bed = "Test Bed",
UnitId = ObjectId.GenerateNewId(),
Configuration = new PointOfCareConfiguration(),
Status = StatusEnum.PointOfCare.Available,
AdmissionId = ObjectId.GenerateNewId(),
Unit = CreateValidUnit(),
UnitName = "Test Unit"
};
}
public static Discharge CreateValidDischarge()
{
return new Discharge
{
Id = ObjectId.GenerateNewId(),
PointOfCareId = ObjectId.GenerateNewId(),
UnitId = ObjectId.GenerateNewId(),
DischargeDate = DateTime.UtcNow,
PatientId = ObjectId.GenerateNewId(),
Destination = "Test Destination",
DestinationOption = CreateValidOptionList(),
ServiceOption = CreateValidOptionList(),
Service = "Test Service",
MedicalDischarge = DateTime.UtcNow,
AdminDischarge = DateTime.UtcNow,
NurseDischarge = DateTime.UtcNow
};
}
public static Patient CreateValidPatient()
{
return new Patient
{
Id = ObjectId.GenerateNewId(),
PatientNumber = "TestPatientNumber",
PatientId = "TestPatientId",
AdmTime = DateTime.UtcNow,
DischargeStatus = new OptionList
{
OptionType = "TestDischargeStatus",
Name = "TestDischargeStatusName",
IconDefault = "TestIcon",
Color = "TestColor",
Description = "TestDescription",
InitDate = DateTime.UtcNow,
EndDate = DateTime.UtcNow.AddDays(7) // Example end date
},
Altable = new OptionList
{
OptionType = "TestAltable",
Name = "TestAltableName",
IconDefault = "TestAltableIcon",
Color = "TestAltableColor",
Description = "TestAltableDescription",
InitDate = DateTime.UtcNow,
EndDate = DateTime.UtcNow.AddDays(7) // Example end date
},
Origin = new OptionList
{
OptionType = "TestOrigin",
Name = "TestOriginName",
IconDefault = "TestOriginIcon",
Color = "TestOriginColor",
Description = "TestOriginDescription",
InitDate = DateTime.UtcNow,
EndDate = DateTime.UtcNow.AddDays(7) // Example end date
}
// Initialize other properties as needed
};
}
public static OptionList CreateValidOptionList()
{
return new OptionList
{
OptionType = "Test Option",
Name = "Test Name",
IconDefault = "Test Icon",
Color = "Test Color",
Description = "Test Description",
InitDate = DateTime.UtcNow,
EndDate = DateTime.UtcNow.AddDays(1)
};
}
private static PatientLocation CreateValidPatientLocation()
{
return new PatientLocation
{
UnitName = "Test Unit",
Bed = "Test Bed",
Room = "Test Room"
};
}
public static Unit CreateValidUnit()
{
return new Unit
{
Id = ObjectId.GenerateNewId(),
Title = "Test Unit",
Name = "Test Unit",
LastUpdate = null,
PointOfCareIds = [],
Status = StatusEnum.Type.Ok,
Configuration = new UnitConfiguration
{
AutoAdt = true,
}
};
}
public static Admission CreateValidAdmission()
{
return new Admission
{
//Id = ObjectId.GenerateNewId(),
AdmissionDate = DateTime.UtcNow,
Nhc = ObjectId.GenerateNewId().ToString(),
UnitId = ObjectId.GenerateNewId(),
PointOfCareId = ObjectId.GenerateNewId(),
Person = new Person
{
FirstName = "Test First Name",
LastName = "Test Last Name"
// Initialize other properties as needed
},
Origin = CreateValidOptionList(),
OriginAux = "Test Origin Aux",
Diagnosis = CreateValidOptionList(),
DiagnosisAux = "Test Diagnosis Aux",
Allergies =
[
CreateValidOptionList(),
CreateValidOptionList()
// Add more allergies as needed
],
Insulation = CreateValidOptionList(),
LanguageBarrier = [CreateValidOptionList()],
PatientLocation = CreateValidPatientLocation()
// Initialize other properties as needed
};
}
public static CardConfig CreateValidCardConfig(ObjectId? id = null)
{
return new CardConfig
{
Id = id ?? ObjectId.GenerateNewId(),
Rows = new List<RowCardConfig>
{
new()
{
Cells = new List<Cell>
{
new() { Type = DisplayConfigEnums.CellType.DemographicCell }
},
GrowPriority = 1,
Type = DisplayConfigEnums.CellType.CellWrapper
}
}
};
}
public static CardDetailsConfig CreateValidCardDetailsNurseConfig(ObjectId? id = null)
{
return new CardDetailsConfig
{
Id = id ?? ObjectId.GenerateNewId(),
NurseRows = new List<RowDetailsConfig>
{
new()
{
Type = DisplayConfigEnums.RowType.Demographic,
Title = "Title details",
Cells = new List<CellDetails>
{
new()
{
Type = DisplayConfigEnums.CellType.CellWrapper,
Cells = new List<CellDetails>
{
new()
{
Type = DisplayConfigEnums.CellType.AllergyCell
},
new()
{
Type = DisplayConfigEnums.CellType.DemographicCell
}
}
}
}
}
}
};
}
public static CardDetailsConfig CreateValidCardDetailsSmartConfig(ObjectId? id = null)
{
return new CardDetailsConfig
{
Id = id ?? ObjectId.GenerateNewId(),
SmartSections = new List<SectionBoxLayout>
{
new()
{
Type = DisplayConfigEnums.RowType.General,
Name = "Title details",
Rows = new List<RowBoxLayout>
{
new()
{
Type = DisplayConfigEnums.CellType.CellWrapper,
Observations = new List<ObservationRowBoxLayout>
{
new()
{
Type = DisplayConfigEnums.CellType.BeaconColor
},
new()
{
Type = DisplayConfigEnums.CellType.Isolation
}
}
}
}
}
}
};
}
public static DisplayConfig CreateValidDisplayConfig(DisplayConfigEnums.DisplayType type, ObjectId? id,
ObjectId? idCard, ObjectId? idDetail)
{
return new DisplayConfig
{
Id = id ?? ObjectId.GenerateNewId(),
CardConfigId = idCard ?? ObjectId.GenerateNewId(),
DetailConfigId = idDetail ?? ObjectId.GenerateNewId(),
Type = type,
FieldList = new List<Field> { new() { Name = "FR", Last = 2 } },
Hospital = "Test Hospital"
};
}
}