=== Summary: 675 files | 7 generated | 484 fresh | 4605 untracked | 4268 adopted | 355 marked | 466 validated-ok | 2+0 stale (sig+body) | 0 skipped | 0 failed | elapsed 11:08:11.442 (40091.44s) ===

This commit is contained in:
julian
2026-06-28 02:50:05 -07:00
parent a19fb90902
commit 586f02a2ca
654 changed files with 5260 additions and 0 deletions
@@ -24,6 +24,7 @@ public class RedisServiceTest
/// <summary>
/// Initializes test dependencies before each test execution by creating a mock <see cref="IDatabase"/> instance and instantiating the <see cref="LockManagerService"/> with a mocked logger and an in-memory lock provider.
/// </summary>
/// <!-- aidoc:v1 sig=d8eb19f body=f7d3912 -->
[SetUp]
public void SetUp()
{
@@ -40,6 +41,7 @@ public class RedisServiceTest
/// <param name="settings">Optional cache settings to apply; when <c>null</c>, a new default <see cref="CacheSettings"/> instance is used.</param>
/// <param name="redisAvailable">Flag indicating whether the Redis service should be marked as available; defaults to <c>true</c>.</param>
/// <returns>A <see cref="RedisService"/> instance with the database and availability state initialized for testing.</returns>
/// <!-- aidoc:v1 sig=3b2c312 body=dfaacef -->
private RedisService CreateSut(CacheSettings? settings = null, bool redisAvailable = true)
{
var sut = new RedisService(
@@ -59,6 +61,7 @@ public class RedisServiceTest
/// <param name="target">The <see cref="RedisService"/> instance whose field will be set.</param>
/// <param name="name">The name of the non-public instance field to assign.</param>
/// <param name="value">The value to assign to the field. Can be null.</param>
/// <!-- aidoc:v1 sig=29fabd1 -->
private static void SetField(object target, string name, object? value)
=> typeof(RedisService)
.GetField(name, BindingFlags.NonPublic | BindingFlags.Instance)!
@@ -67,6 +70,7 @@ public class RedisServiceTest
/// <summary>
/// Configures the mock database to return a successful result (<c>true</c>) for any invocation of <c>StringSetAsync</c>, regardless of the supplied key, value, expiry, overwrite flag, condition, or command flags.
/// </summary>
/// <!-- aidoc:v1 sig=98682b4 -->
private void SetupStringSetAsync()
=> _mockDb
.Setup(db => db.StringSetAsync(
@@ -77,6 +81,7 @@ public class RedisServiceTest
/// <summary>
/// Configures the mock Redis database to handle <c>KeyExpire</c> calls by returning <c>true</c> for any combination of key, expiration, condition, and command flag arguments.
/// </summary>
/// <!-- aidoc:v1 sig=0ffd573 -->
private void SetupKeyExpire()
=> _mockDb
.Setup(db => db.KeyExpire(
@@ -88,6 +93,7 @@ public class RedisServiceTest
/// <summary>
/// Verifies that <c>GetOrSetObjectAsync</c> invokes the supplied factory when Redis is unavailable, returning the factory's result without attempting any Redis read or write operations.
/// </summary>
/// <!-- aidoc:v1 sig=1a73907 body=b6ad74e -->
[Test]
public async Task GetOrSetObjectAsync_ExecutesFactory_WhenRedisUnavailable()
{
@@ -111,6 +117,7 @@ public class RedisServiceTest
/// when a value is present in the cache, without invoking the factory delegate and without
/// attempting to write back to Redis.
/// </summary>
/// <!-- aidoc:v1 sig=ff045fa body=9481052 -->
[Test]
public async Task GetOrSetObjectAsync_ReturnsCachedObject_WhenRedisHit()
{
@@ -138,6 +145,7 @@ public class RedisServiceTest
/// Verifies that <c>GetObjectAsync</c> calls the underlying Redis <c>KeyExpire</c> command with the configured TTL
/// when the <c>updateExpiration</c> flag is set to <c>true</c>, ensuring cache entries are refreshed upon a successful hit.
/// </summary>
/// <!-- aidoc:v1 sig=066b548 body=8421fd4 -->
[Test]
public async Task GetObjectAsync_CallsKeyExpire_WhenUpdateExpirationIsTrue()
{
@@ -167,6 +175,7 @@ public class RedisServiceTest
/// Verifies that <c>GetObjectAsync</c> does not invoke the Redis key expiration command
/// when the caller explicitly requests that the existing expiration be left unchanged.
/// </summary>
/// <!-- aidoc:v1 sig=e10e6a3 body=d0256b9 -->
[Test]
public async Task GetObjectAsync_DoesNotCallKeyExpire_WhenUpdateExpirationIsFalse()
{
@@ -190,6 +199,7 @@ public class RedisServiceTest
/// Ensures the factory delegate is executed, the deserialized value matches the factory output, and the
/// object is written to cache with the expected expiration.
/// </summary>
/// <!-- aidoc:v1 sig=775bb73 body=a143def -->
[Test]
public async Task GetOrSetObjectAsync_InvokesFactoryAndPersists_WhenCacheMiss()
{
@@ -232,6 +242,7 @@ public class RedisServiceTest
/// Verifies that when the cache lookup returns no value and the factory delegate produces <c>null</c>,
/// the method returns <c>null</c> and does not persist any value to the underlying cache store.
/// </summary>
/// <!-- aidoc:v1 sig=67a4b2b body=95662d2 -->
[Test]
public async Task GetOrSetObjectAsync_DoesNotPersist_WhenFactoryReturnsNull()
{
@@ -256,6 +267,7 @@ public class RedisServiceTest
/// Verifies that <c>GetObjectAsync</c> successfully retrieves and deserializes the stored object while skipping the
/// key-expiration refresh when <c>updateExpiration</c> is set to <c>false</c>, ensuring <c>KeyExpire</c> is never invoked.
/// </summary>
/// <!-- aidoc:v1 sig=f1dc303 body=114b61f -->
[Test]
public async Task GetObjectAsync_ReturnsObject_AndSkipsKeyExpire_WhenUpdateExpirationFalse()
{
@@ -280,6 +292,7 @@ public class RedisServiceTest
/// Verifies that <c>SetObjectAsync</c> serializes the supplied object to JSON and persists it in Redis
/// with the entity-specific TTL (600 seconds) configured for the "Patients" entity in <see cref="CacheSettings"/>.
/// </summary>
/// <!-- aidoc:v1 sig=053126b body=05a7fbb -->
[Test]
public async Task SetObjectAsync_SerializesToJson_AndPersistsWithEntityTtl()
{