rama creada apartir de master en j

This commit is contained in:
jrojas
2026-06-26 10:29:23 +02:00
parent 319fd3dfb0
commit c1517fda87
2810 changed files with 1927392 additions and 25392 deletions
+65 -1
View File
@@ -4,35 +4,70 @@ using Serilog.Events;
namespace adas_core.Test.Models;
/// <summary>
/// Represents a fake implementation of the ILogger interface, typically used as a test double to simulate logging behavior.
/// </summary>
public class FakeLogger : ILogger
{
public List<string> Messages { get; } = [];
/// <summary>
/// Creates a logger context enriched with the specified <see cref="ILogEventEnricher"/> instances. In this implementation, the enrichers are not applied and the current <see cref="ILogger"/> instance is returned unchanged.
/// </summary>
/// <param name="enrichers">The collection of enrichers intended to add contextual properties to log events.</param>
/// <returns>The current <see cref="ILogger"/> instance, without the supplied enrichers applied.</returns>
public ILogger ForContext(IEnumerable<ILogEventEnricher> enrichers)
{
return this;
}
/// <summary>
/// Creates a logger context enriched with the specified property and value, returning the same logger instance.
/// </summary>
/// <param name="propertyName">The name of the property to add to the logger context.</param>
/// <param name="value">The value associated with the property. Can be null.</param>
/// <param name="destructureObjects">Indicates whether complex objects should be destructured. Defaults to false.</param>
/// <returns>The current <see cref="ILogger"/> instance.</returns>
public ILogger ForContext(string propertyName, object? value, bool destructureObjects = false)
{
return this;
}
/// <summary>
/// Creates a logger context associated with the specified source type by returning the current <see cref="ILogger"/> instance.
/// </summary>
/// <typeparam name="TSource">The source type used to enrich the logger context.</typeparam>
/// <returns>The current <see cref="ILogger"/> instance.</returns>
public ILogger ForContext<TSource>()
{
return this;
}
/// <summary>
/// Returns the current logger instance, ignoring the provided source type. Provides a no-op context enrichment for log messages.
/// </summary>
/// <param name="source">The source type used to enrich the logger context.</param>
/// <returns>The current <see cref="ILogger"/> instance.</returns>
public ILogger ForContext(Type source)
{
return this;
}
/// <summary>
/// Appends the rendered message of the provided log event to the internal messages collection.
/// </summary>
/// <param name="logEvent">The log event whose rendered message will be added to the collection.</param>
public void Write(LogEvent logEvent)
{
Messages.Add(logEvent.RenderMessage());
}
/// <summary>
/// Writes a log message at the specified level to the internal messages collection, formatting it with the provided property values.
/// </summary>
/// <param name="level">The severity level of the log event.</param>
/// <param name="messageTemplate">The message template containing placeholders for the property values.</param>
/// <param name="propertyValues">An optional array of objects to format the message template. Can be <see langword="null"/>.</param>
public void Write(LogEventLevel level, string messageTemplate, params object?[]? propertyValues)
{
// Manejar la situación donde propertyValues es nulo, si es necesario
@@ -42,13 +77,30 @@ public class FakeLogger : ILogger
}
/// <summary>
/// Writes a log entry by formatting the provided message template with the given property value and adding it to the messages collection.
/// </summary>
/// <typeparam name="T">The type of the property value to be substituted into the message template.</typeparam>
/// <param name="level">The log event level associated with the entry being written.</param>
/// <param name="messageTemplate">The message template containing a format placeholder for the property value.</param>
/// <param name="propertyValue">The value to be inserted into the message template.</param>
public void Write<T>(LogEventLevel level, string messageTemplate, T propertyValue)
{
Messages.Add(string.Format(messageTemplate, propertyValue));
}
/// <summary>
/// Captures a log entry by appending the formatted message to the internal <c>Messages</c> collection.
/// When <paramref name="propertyValues"/> is provided, the <paramref name="messageTemplate"/> is formatted with those values; otherwise the template is stored as-is.
/// If <paramref name="exception"/> is not null, its message is appended as an additional entry.
/// </summary>
/// <param name="level">The severity level of the log event.</param>
/// <param name="exception">An optional exception whose message is recorded when not null.</param>
/// <param name="messageTemplate">The message template to log, used directly when <paramref name="propertyValues"/> is null.</param>
/// <param name="propertyValues">Optional values to substitute into <paramref name="messageTemplate"/> via <c>string.Format</c>.</param>
public void Write(LogEventLevel level, Exception? exception, string messageTemplate,
params object?[]? propertyValues)
params object?[]? propertyValues)
{
Messages.Add(propertyValues == null ? messageTemplate : string.Format(messageTemplate, propertyValues));
@@ -56,11 +108,23 @@ public class FakeLogger : ILogger
}
/// <summary>
/// Determines whether logging is enabled for the specified log event level. Currently returns <c>true</c> unconditionally, allowing all log levels to be processed.
/// </summary>
/// <param name="level">The log event level to evaluate.</param>
/// <returns><c>true</c> if logging is enabled for the given level; otherwise, <c>false</c>.</returns>
public bool IsEnabled(LogEventLevel level)
{
return true;
}
/// <summary>
/// Writes a log entry by formatting the provided message template with the supplied property value and appending it to the Messages collection. If an exception is supplied, its message is also appended to the collection.
/// </summary>
/// <param name="level">The severity level of the log event.</param>
/// <param name="exception">An optional exception whose message, when not null, is added to the Messages collection after the formatted message.</param>
/// <param name="messageTemplate">The message template string used to format the log entry.</param>
/// <param name="propertyValue">The value to be substituted into the message template.</param>
public void Write<T>(LogEventLevel level, Exception? exception, string messageTemplate, T propertyValue)
{
Messages.Add(string.Format(messageTemplate, propertyValue));
@@ -12,72 +12,78 @@ namespace adas_core.Test.Models.SignalR;
[TestFixture]
public class SubscriberGroupedTest
{
/// <summary>
/// Initializes test fixtures used by grouped observation and WebSocket subscriber tests, including
/// <see cref="GroupedObservation"/>, <see cref="GroupedField"/>, <see cref="WsSubscriber"/>, and
/// <see cref="WsSubscriberGrouped"/> instances configured for two distinct patients with shift- and
/// hour-based regularities and last/last-filled result mappings.
/// </summary>
[SetUp]
public void Setup()
{
// Set up GroupedObservation
_go = new GroupedObservation
public void Setup()
{
PatientId = _patient1,
Name = "GroupedObservationTest1",
Group = "GroupedObservationTest1",
Observations = []
};
_go2 = new GroupedObservation
{
PatientId = _patient2,
Name = "GroupedObservationTest2",
Group = "GroupedObservationTest2",
Observations = []
};
// Set up GroupedField
_gf1 = new GroupedField
{
Name = "GroupedObservationTest1",
Group = "GroupedFieldTest1",
StartTimeShift = ["00:59", "04:59", "08:59", "12:59", "16:59", "20:59"],
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Shift,
Result = [GroupedObservationEnum.Result.Last]
};
_gf2 = new GroupedField
{
Names = ["GroupedObservationTest2", "GroupedObservationTest1"],
Group = "GroupedFieldTest2",
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Hour,
Result = [GroupedObservationEnum.Result.Last, GroupedObservationEnum.Result.LastFilled]
};
// Set up WebSocketSubscriber
_ws1 = new WsSubscriber("1234")
{
Id = "1234",
Box = "Box1",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
_ws2 = new WsSubscriber("1234")
{
Id = "5321",
Box = "Box2",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
// Set up groupedFields for subscribers
_ws1.GroupedFields = [_gf1];
_ws2.GroupedFields = [_gf1, _gf2];
// Set up WsSubscriberGrouped
_wsBase = new WsSubscriberGrouped(_patient1, _ws1.Id, "Romance Standard Time", _gf1, _go, delegate { });
_wsBase2 = new WsSubscriberGrouped(_patient2, _ws2.Id, "Romance Standard Time", _gf2, _go2, delegate { });
}
// Set up GroupedObservation
_go = new GroupedObservation
{
PatientId = _patient1,
Name = "GroupedObservationTest1",
Group = "GroupedObservationTest1",
Observations = []
};
_go2 = new GroupedObservation
{
PatientId = _patient2,
Name = "GroupedObservationTest2",
Group = "GroupedObservationTest2",
Observations = []
};
// Set up GroupedField
_gf1 = new GroupedField
{
Name = "GroupedObservationTest1",
Group = "GroupedFieldTest1",
StartTimeShift = ["00:59", "04:59", "08:59", "12:59", "16:59", "20:59"],
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Shift,
Result = [GroupedObservationEnum.Result.Last]
};
_gf2 = new GroupedField
{
Names = ["GroupedObservationTest2", "GroupedObservationTest1"],
Group = "GroupedFieldTest2",
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Hour,
Result = [GroupedObservationEnum.Result.Last, GroupedObservationEnum.Result.LastFilled]
};
// Set up WebSocketSubscriber
_ws1 = new WsSubscriber("1234")
{
Id = "1234",
Box = "Box1",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
_ws2 = new WsSubscriber("1234")
{
Id = "5321",
Box = "Box2",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
// Set up groupedFields for subscribers
_ws1.GroupedFields = [_gf1];
_ws2.GroupedFields = [_gf1, _gf2];
// Set up WsSubscriberGrouped
_wsBase = new WsSubscriberGrouped(_patient1, _ws1.Id, "Romance Standard Time", _gf1, _go, delegate { });
_wsBase2 = new WsSubscriberGrouped(_patient2, _ws2.Id, "Romance Standard Time", _gf2, _go2, delegate { });
}
private GroupedObservation _go;
private GroupedObservation _go2;
@@ -94,145 +100,161 @@ public class SubscriberGroupedTest
private readonly ObjectId _patient1 = ObjectId.GenerateNewId();
private readonly ObjectId _patient2 = ObjectId.GenerateNewId();
/// <summary>
/// Verifies that the <see cref="ISubscriberGroupedService.GetGrouped"/> method returns the list of grouped subscribers provided by the mocked service.
/// Ensures the service correctly returns the expected collection of <see cref="WsSubscriberGrouped"/> items without modification.
/// </summary>
[Test]
public void GetGroupeds_ReturnsExpectedResult()
{
var mockSubscriberGrouped = new List<WsSubscriberGrouped>
public void GetGroupeds_ReturnsExpectedResult()
{
new(_patient1, _ws1.Id, "Romance Standard Time", _gf1, _go, delegate { }),
new(_patient2, _ws1.Id, "Romance Standard Time", _gf1, _go, delegate { })
};
var mockSubscriberGroupedService = new Mock<ISubscriberGroupedService>();
mockSubscriberGroupedService.Setup(x => x.GetGrouped()).Returns(mockSubscriberGrouped);
var result = mockSubscriberGroupedService.Object.GetGrouped();
Assert.That(result, Is.EqualTo(mockSubscriberGrouped));
}
var mockSubscriberGrouped = new List<WsSubscriberGrouped>
{
new(_patient1, _ws1.Id, "Romance Standard Time", _gf1, _go, delegate { }),
new(_patient2, _ws1.Id, "Romance Standard Time", _gf1, _go, delegate { })
};
var mockSubscriberGroupedService = new Mock<ISubscriberGroupedService>();
mockSubscriberGroupedService.Setup(x => x.GetGrouped()).Returns(mockSubscriberGrouped);
var result = mockSubscriberGroupedService.Object.GetGrouped();
Assert.That(result, Is.EqualTo(mockSubscriberGrouped));
}
/// <summary>
/// Verifies the behavior of the <c>Compare</c> extension method by asserting that it returns <c>true</c> when the gender and patient identifiers match the active context, and <c>false</c> when they do not, covering both the primary and secondary contexts.
/// </summary>
[Test]
public void Compare_ExtensionResult()
{
using (Assert.EnterMultipleScope())
public void Compare_ExtensionResult()
{
Assert.That(_wsBase.Compare(_gf1, _go.PatientId), Is.True);
Assert.That(_wsBase.Compare(_gf1, _go2.PatientId), Is.False);
Assert.That(_wsBase.Compare(_gf2, _go.PatientId), Is.False);
Assert.That(_wsBase2.Compare(_gf2, _go2.PatientId), Is.True);
};
}
using (Assert.EnterMultipleScope())
{
Assert.That(_wsBase.Compare(_gf1, _go.PatientId), Is.True);
Assert.That(_wsBase.Compare(_gf1, _go2.PatientId), Is.False);
Assert.That(_wsBase.Compare(_gf2, _go.PatientId), Is.False);
Assert.That(_wsBase2.Compare(_gf2, _go2.PatientId), Is.True);
};
}
/// <summary>
/// Verifies that a new patient observation is considered relevant for its group when it is the first observation recorded within the current hour.
/// </summary>
[Test]
public void Observation_is_rrelevant_because_is_the_first_in_hour()
{
var obs = new PatientObservation
public void Observation_is_rrelevant_because_is_the_first_in_hour()
{
Time = DateTime.UtcNow,
Value = 5
};
Assert.That(_wsBase.IsNewObservationRelevantForGroup(obs), Is.True);
}
var obs = new PatientObservation
{
Time = DateTime.UtcNow,
Value = 5
};
Assert.That(_wsBase.IsNewObservationRelevantForGroup(obs), Is.True);
}
/// <summary>
/// Verifies that a new patient observation is considered relevant for a grouped observation when an observation already exists within the configured hour interval and the grouping uses the Max result.
/// </summary>
[Test]
public void Grouped_Observation_Already_Observations_In_Hour_Should_Be_Relevant_By_Max_Result()
{
var patientId = ObjectId.GenerateNewId();
var grouped = new GroupedObservation
public void Grouped_Observation_Already_Observations_In_Hour_Should_Be_Relevant_By_Max_Result()
{
PatientId = patientId,
Name = "GroupedObservationTest1",
Group = "GroupedObservationTest1",
Observations =
[
new GroupedObservationObs
{
Max = new GroupedObservationObsValue(5, DateTime.UtcNow)
}
]
};
var wsSubscriber = new WsSubscriber("1234")
{
Id = "1234",
Box = "Box1",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
var groupedField = new GroupedField
{
Names = ["GroupedObservationTest2", "GroupedObservationTest1"],
Group = "GroupedFieldTest2",
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Hour,
Result = [GroupedObservationEnum.Result.Max]
};
var newObservation = new PatientObservation
{
PatientId = patientId,
Time = DateTime.UtcNow,
Value = 8
};
var wsGrouped = new WsSubscriberGrouped(patientId, wsSubscriber.Id, "", groupedField, grouped, delegate { });
//for utc.now two observations, last was 5 and now is 8 result is by Max, should be relevant
Assert.That(wsGrouped.IsNewObservationRelevantForGroup(newObservation), Is.True);
}
var patientId = ObjectId.GenerateNewId();
var grouped = new GroupedObservation
{
PatientId = patientId,
Name = "GroupedObservationTest1",
Group = "GroupedObservationTest1",
Observations =
[
new GroupedObservationObs
{
Max = new GroupedObservationObsValue(5, DateTime.UtcNow)
}
]
};
var wsSubscriber = new WsSubscriber("1234")
{
Id = "1234",
Box = "Box1",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
var groupedField = new GroupedField
{
Names = ["GroupedObservationTest2", "GroupedObservationTest1"],
Group = "GroupedFieldTest2",
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Hour,
Result = [GroupedObservationEnum.Result.Max]
};
var newObservation = new PatientObservation
{
PatientId = patientId,
Time = DateTime.UtcNow,
Value = 8
};
var wsGrouped = new WsSubscriberGrouped(patientId, wsSubscriber.Id, "", groupedField, grouped, delegate { });
//for utc.now two observations, last was 5 and now is 8 result is by Max, should be relevant
Assert.That(wsGrouped.IsNewObservationRelevantForGroup(newObservation), Is.True);
}
/// <summary>
/// Verifies that a new observation is considered not relevant for a grouped observation when the grouping rule is set to "Max", the regularity is "Hour", an observation already exists within the same hour, and the new observation's value does not exceed the existing maximum value.
/// </summary>
[Test]
public void Grouped_Observation_Already_Observations_In_Hour_Should_Be_IRelevant_By_Max_Result()
{
var patientId = ObjectId.GenerateNewId();
var grouped = new GroupedObservation
public void Grouped_Observation_Already_Observations_In_Hour_Should_Be_IRelevant_By_Max_Result()
{
PatientId = patientId,
Name = "GroupedObservationTest1",
Group = "GroupedObservationTest1",
Observations =
[
new GroupedObservationObs
{
Max = new GroupedObservationObsValue(5, DateTime.UtcNow),
Time = DateTime.UtcNow
}
]
};
var wsSubscriber = new WsSubscriber("1234")
{
Id = "1234",
Box = "Box1",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
var groupedField = new GroupedField
{
Names = ["GroupedObservationTest2", "GroupedObservationTest1"],
Group = "GroupedFieldTest2",
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Hour,
Result = [GroupedObservationEnum.Result.Max]
};
var newObservation = new PatientObservation
{
PatientId = patientId,
Time = DateTime.UtcNow,
Value = 4
};
var wsGrouped = new WsSubscriberGrouped(patientId, wsSubscriber.Id, "", groupedField, grouped, delegate { });
//for utc.now two observations, last was 5 and now is 4 result is by Max, should be Irelevant
Assert.That(wsGrouped.IsNewObservationRelevantForGroup(newObservation), Is.False);
}
var patientId = ObjectId.GenerateNewId();
var grouped = new GroupedObservation
{
PatientId = patientId,
Name = "GroupedObservationTest1",
Group = "GroupedObservationTest1",
Observations =
[
new GroupedObservationObs
{
Max = new GroupedObservationObsValue(5, DateTime.UtcNow),
Time = DateTime.UtcNow
}
]
};
var wsSubscriber = new WsSubscriber("1234")
{
Id = "1234",
Box = "Box1",
Section = "Section1",
Version = "1.0.0",
GroupedFields = [],
SubscriptionType = SubscriptionEnum.WsType.Box
};
var groupedField = new GroupedField
{
Names = ["GroupedObservationTest2", "GroupedObservationTest1"],
Group = "GroupedFieldTest2",
Max = 24,
Regularity = GroupedObservationEnum.Regularity.Hour,
Result = [GroupedObservationEnum.Result.Max]
};
var newObservation = new PatientObservation
{
PatientId = patientId,
Time = DateTime.UtcNow,
Value = 4
};
var wsGrouped = new WsSubscriberGrouped(patientId, wsSubscriber.Id, "", groupedField, grouped, delegate { });
//for utc.now two observations, last was 5 and now is 4 result is by Max, should be Irelevant
Assert.That(wsGrouped.IsNewObservationRelevantForGroup(newObservation), Is.False);
}
}