using ManagerService.Data; using ManagerService.Services; using ManagerService.Tests.Infrastructure; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging.Abstractions; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Xunit; namespace ManagerService.Tests.Services { /// /// La purge s'appuie sur ExecuteDeleteAsync, que le provider InMemory ne sait pas /// traduire — un test là-bas ne dirait rien de ce qui se passe en production. Ceux-ci /// s'exécutent contre un vrai PostgreSQL, et se sautent proprement sans démon Docker. /// [Collection(PostgresCollection.Name)] public class AuditLogPurgePostgresTests { private readonly PostgresFixture _postgres; public AuditLogPurgePostgresTests(PostgresFixture postgres) { _postgres = postgres; } private static AuditLogPurgeService BuildService(MyInfoMateDbContext db, int retentionDays) { var configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["Audit:RetentionDays"] = retentionDays.ToString() }) .Build(); return new AuditLogPurgeService(db, configuration, NullLogger.Instance); } private static AuditLog Entry(string id, DateTime timestamp) => new AuditLog { Id = id, EntityType = "User", EntityId = "u1", Action = "Update", UserId = "u1", Timestamp = timestamp }; [SkippableFact] public async Task PurgeAsync_DeletesOnlyBeyondTheWindow() { Skip.IfNot(_postgres.Available, _postgres.SkipReason); using var db = _postgres.CreateMigratedContext("audit_purge"); db.AuditLogs.AddRange( Entry("vieux", DateTime.UtcNow.AddDays(-400)), Entry("recent", DateTime.UtcNow.AddDays(-30))); db.SaveChanges(); await BuildService(db, AuditLogPurgeService.DefaultRetentionDays).PurgeAsync(); Assert.Equal("recent", Assert.Single(db.AuditLogs).Id); } } }