using Microsoft.EntityFrameworkCore; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Deployment; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Instances; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites; using ZB.MOM.WW.ScadaBridge.Commons.Entities.Templates; using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums; using ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Repositories; namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Tests; /// /// Coverage for IDeploymentManagerRepository.GetDeployedRevisionHashesAsync — the /// fleet-wide InstanceId → RevisionHash projection the pending-updates aggregate reads once /// per cache TTL. Uses the shared SQLite in-memory fixture with real FK enforcement. /// public class DeployedRevisionHashesRepositoryTests : IDisposable { private readonly ScadaBridgeDbContext _context; private readonly DeploymentManagerRepository _repository; /// Creates the in-memory context and the repository under test. public DeployedRevisionHashesRepositoryTests() { _context = SqliteTestHelper.CreateInMemoryContext(); _repository = new DeploymentManagerRepository(_context); } /// Closes and disposes the in-memory context. public void Dispose() { _context.Database.CloseConnection(); _context.Dispose(); GC.SuppressFinalize(this); } private async Task SeedInstanceAsync(string uniqueName) { var site = new Site($"Site-{uniqueName}", $"SI-{uniqueName}"); var template = new Template($"T-{uniqueName}"); _context.Sites.Add(site); _context.Templates.Add(template); await _context.SaveChangesAsync(); var instance = new Instance(uniqueName) { SiteId = site.Id, TemplateId = template.Id, State = InstanceState.Enabled, }; _context.Instances.Add(instance); await _context.SaveChangesAsync(); return instance.Id; } private async Task SeedSnapshotAsync(int instanceId, string deploymentId, string revisionHash) { var snapshot = new DeployedConfigSnapshot(deploymentId, revisionHash, "{\"big\":\"payload\"}") { InstanceId = instanceId, }; _context.Set().Add(snapshot); await _context.SaveChangesAsync(); } [Fact] public async Task GetDeployedRevisionHashes_returns_every_snapshot_keyed_by_instance() { var first = await SeedInstanceAsync("Pump-01"); var second = await SeedInstanceAsync("Pump-02"); await SeedSnapshotAsync(first, "dep-1", "hash-one"); await SeedSnapshotAsync(second, "dep-2", "hash-two"); var hashes = await _repository.GetDeployedRevisionHashesAsync(); Assert.Equal(2, hashes.Count); Assert.Equal("hash-one", hashes[first]); Assert.Equal("hash-two", hashes[second]); } [Fact] public async Task GetDeployedRevisionHashes_returns_empty_when_nothing_is_deployed() { await SeedInstanceAsync("Pump-01"); var hashes = await _repository.GetDeployedRevisionHashesAsync(); Assert.Empty(hashes); } }