using Microsoft.Extensions.Options; using ZB.MOM.WW.GalaxyRepository; namespace ZB.MOM.WW.GalaxyRepository.Tests; /// /// Round-trip tests for the real over a temp /// file path: save then load, no-op when persistence is disabled, and clean disposal. /// public sealed class GalaxyHierarchySnapshotStoreTests : IDisposable { private readonly string _path = Path.Combine( Path.GetTempPath(), $"galaxyrepo-snap-{Guid.NewGuid():N}.json"); public void Dispose() { if (File.Exists(_path)) { File.Delete(_path); } } private static GalaxyHierarchySnapshot SampleSnapshot() => new( LastDeployTime: new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero), SavedAt: new DateTimeOffset(2026, 1, 1, 12, 0, 0, TimeSpan.Zero), Hierarchy: [ new GalaxyHierarchyRow { GobjectId = 1, TagName = "Area1", IsArea = true }, new GalaxyHierarchyRow { GobjectId = 2, TagName = "Pump01", ParentGobjectId = 1 }, ], Attributes: [ new GalaxyAttributeRow { GobjectId = 2, AttributeName = "PV", FullTagReference = "Pump01.PV", IsHistorized = true }, ]); [Fact] public async Task SaveThenLoad_RoundTripsTheSnapshot() { using GalaxyHierarchySnapshotStore store = new( Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = true, SnapshotCachePath = _path })); await store.SaveAsync(SampleSnapshot(), CancellationToken.None); GalaxyHierarchySnapshot? loaded = await store.TryLoadAsync(CancellationToken.None); Assert.NotNull(loaded); Assert.Equal(2, loaded!.Hierarchy.Count); Assert.Single(loaded.Attributes); Assert.Equal("Pump01.PV", loaded.Attributes[0].FullTagReference); Assert.True(loaded.Attributes[0].IsHistorized); Assert.Equal(SampleSnapshot().LastDeployTime, loaded.LastDeployTime); } [Fact] public async Task SaveAndLoad_AreNoOps_WhenPersistenceDisabled() { using GalaxyHierarchySnapshotStore store = new( Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = false, SnapshotCachePath = _path })); await store.SaveAsync(SampleSnapshot(), CancellationToken.None); Assert.False(File.Exists(_path)); Assert.Null(await store.TryLoadAsync(CancellationToken.None)); } [Fact] public async Task TryLoad_ReturnsNull_WhenNoFileExists() { using GalaxyHierarchySnapshotStore store = new( Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = true, SnapshotCachePath = _path })); Assert.Null(await store.TryLoadAsync(CancellationToken.None)); } [Fact] public async Task TryLoad_ReturnsNull_WhenFileIsNotValidJson() { await File.WriteAllTextAsync(_path, "{ this is not valid json"); using GalaxyHierarchySnapshotStore store = new( Options.Create(new GalaxyRepositoryOptions { PersistSnapshot = true, SnapshotCachePath = _path })); Assert.Null(await store.TryLoadAsync(CancellationToken.None)); } }