using Manager.Services; using ManagerService.Controllers; using ManagerService.Data; using ManagerService.DTOs; using ManagerService.Helpers; using ManagerService.Services; using ManagerService.Tests.Infrastructure; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging.Abstractions; using Xunit; namespace ManagerService.Tests.Controllers { public class InstanceControllerTests { private InstanceController BuildController(MyInfoMateDbContext db) { var cfg = FakeMongoConfig.Create(); var instanceService = new InstanceDatabaseService(cfg); var userService = new UserDatabaseService(cfg); var profileLogic = new ProfileLogic(NullLogger.Instance); var apiKeyService = new ApiKeyDatabaseService(db); return new InstanceController( NullLogger.Instance, instanceService, userService, profileLogic, db, apiKeyService); } // ── CREATE ─────────────────────────────────────────────────────────── [Fact] public void CreateInstance_DuplicateName_Returns409() { using var db = DbContextFactory.Create(); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow }); db.SaveChanges(); var result = BuildController(db).CreateInstance(new InstanceDTO { name = "Musée" }); Assert.IsType(result); } [Fact] public void CreateInstance_ValidDto_PersistsAndReturnsDto() { using var db = DbContextFactory.Create(); var result = BuildController(db).CreateInstance(new InstanceDTO { name = "Nouveau" }); Assert.IsType(result); Assert.Equal(1, db.Instances.Count()); } [Fact] public void CreateInstance_NullDto_Returns400() { using var db = DbContextFactory.Create(); var result = BuildController(db).CreateInstance(null!); Assert.IsType(result); } // ── UPDATE ─────────────────────────────────────────────────────────── [Fact] public void Updateinstance_ClearSubscriptionPlan_SetsNull() { using var db = DbContextFactory.Create(); db.SubscriptionPlans.Add(new SubscriptionPlan { Id = "p1", Name = "Starter" }); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", SubscriptionPlanId = "p1", DateCreation = DateTime.UtcNow }); db.SaveChanges(); // subscriptionPlanId = "" → doit effacer le plan var result = BuildController(db).Updateinstance(new InstanceDTO { id = "i1", subscriptionPlanId = "" }); Assert.IsType(result); Assert.Null(db.Instances.First().SubscriptionPlanId); } [Fact] public void Updateinstance_SetSubscriptionPlan_Updates() { using var db = DbContextFactory.Create(); db.SubscriptionPlans.Add(new SubscriptionPlan { Id = "p1", Name = "Starter" }); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow }); db.SaveChanges(); var result = BuildController(db).Updateinstance(new InstanceDTO { id = "i1", subscriptionPlanId = "p1" }); Assert.IsType(result); Assert.Equal("p1", db.Instances.First().SubscriptionPlanId); } [Fact] public void Updateinstance_UnknownId_Returns404() { using var db = DbContextFactory.Create(); var result = BuildController(db).Updateinstance(new InstanceDTO { id = "unknown", name = "X" }); Assert.IsType(result); } // ── GET QUOTA ──────────────────────────────────────────────────────── [Fact] public void GetQuota_UnknownInstance_Returns404() { using var db = DbContextFactory.Create(); var result = BuildController(db).GetQuota("unknown"); Assert.IsType(result); } [Fact] public void GetQuota_NoSubscriptionPlan_ReturnsZeroQuotas() { using var db = DbContextFactory.Create(); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow }); db.SaveChanges(); var result = BuildController(db).GetQuota("i1"); var ok = Assert.IsType(result); var dto = Assert.IsType(ok.Value); Assert.Equal(0, dto.storageQuotaBytes); Assert.Equal(0, dto.aiRequestsPerMonth); } [Fact] public void GetQuota_WithPlan_ReturnsQuotaFromPlan() { using var db = DbContextFactory.Create(); db.SubscriptionPlans.Add(new SubscriptionPlan { Id = "p1", Name = "Standard", StorageQuotaBytes = 10_000_000_000L, AiRequestsPerMonth = 100 }); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", SubscriptionPlanId = "p1", DateCreation = DateTime.UtcNow }); db.SaveChanges(); var result = BuildController(db).GetQuota("i1"); var ok = Assert.IsType(result); var dto = Assert.IsType(ok.Value); Assert.Equal(10_000_000_000L, dto.storageQuotaBytes); Assert.Equal(100, dto.aiRequestsPerMonth); } [Fact] public void GetQuota_SumsResourceSizeBytes() { using var db = DbContextFactory.Create(); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow }); db.Resources.AddRange( new Resource { Id = "r1", InstanceId = "i1", Label = "img1", Type = ResourceType.Image, SizeBytes = 1000 }, new Resource { Id = "r2", InstanceId = "i1", Label = "img2", Type = ResourceType.Image, SizeBytes = 2000 }, new Resource { Id = "r3", InstanceId = "other", Label = "img3", Type = ResourceType.Image, SizeBytes = 9999 } ); db.SaveChanges(); var result = BuildController(db).GetQuota("i1"); var ok = Assert.IsType(result); var dto = Assert.IsType(ok.Value); Assert.Equal(3000, dto.storageUsedBytes); } [Fact] public void GetQuota_AiUsage_CurrentMonth_ReturnsCount() { using var db = DbContextFactory.Create(); var monthKey = DateTime.UtcNow.ToString("yyyy-MM"); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow, AiRequestsThisMonth = 7, AiUsageMonthKey = monthKey }); db.SaveChanges(); var result = BuildController(db).GetQuota("i1"); var ok = Assert.IsType(result); var dto = Assert.IsType(ok.Value); Assert.Equal(7, dto.aiRequestsUsed); } [Fact] public void GetQuota_AiUsage_PreviousMonth_ReturnsZero() { using var db = DbContextFactory.Create(); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow, AiRequestsThisMonth = 7, AiUsageMonthKey = "2020-01" }); db.SaveChanges(); var result = BuildController(db).GetQuota("i1"); var ok = Assert.IsType(result); var dto = Assert.IsType(ok.Value); Assert.Equal(0, dto.aiRequestsUsed); } // ── DELETE ─────────────────────────────────────────────────────────── [Fact] public void DeleteInstance_CascadesUsers() { using var db = DbContextFactory.Create(); db.Instances.Add(new Instance { Id = "i1", Name = "Musée", DateCreation = DateTime.UtcNow }); db.Users.AddRange( new User { Id = "u1", Email = "a@test.be", Password = "x", LastName = "A", Token = "t1", InstanceId = "i1" }, new User { Id = "u2", Email = "b@test.be", Password = "x", LastName = "B", Token = "t2", InstanceId = "i1" } ); db.SaveChanges(); var result = BuildController(db).DeleteInstance("i1"); var status = Assert.IsType(result); Assert.Equal(202, status.StatusCode); Assert.Equal(0, db.Instances.Count()); Assert.Equal(0, db.Users.Count()); } [Fact] public void DeleteInstance_UnknownId_Returns404() { using var db = DbContextFactory.Create(); var result = BuildController(db).DeleteInstance("unknown"); Assert.IsType(result); } } }