using MxGateway.Server.Galaxy; namespace MxGateway.Tests.Galaxy; public sealed class GalaxyDeployNotifierTests { [Fact] public async Task SubscribeAsync_NoLatestEvent_BlocksUntilPublish() { GalaxyDeployNotifier notifier = new(); using CancellationTokenSource cts = new(); IAsyncEnumerator enumerator = notifier .SubscribeAsync(cts.Token) .GetAsyncEnumerator(cts.Token); ValueTask moveNext = enumerator.MoveNextAsync(); Assert.False(moveNext.IsCompleted); GalaxyDeployEventInfo published = new( Sequence: 1, ObservedAt: DateTimeOffset.UtcNow, TimeOfLastDeploy: DateTimeOffset.UtcNow, ObjectCount: 5, AttributeCount: 25); notifier.Publish(published); Assert.True(await moveNext.AsTask().WaitAsync(TimeSpan.FromSeconds(1))); Assert.Same(published, enumerator.Current); await cts.CancelAsync(); await enumerator.DisposeAsync(); } [Fact] public async Task SubscribeAsync_WithLatestEvent_BootstrapsImmediately() { GalaxyDeployNotifier notifier = new(); GalaxyDeployEventInfo first = new(1, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 3, 9); notifier.Publish(first); using CancellationTokenSource cts = new(); await using IAsyncEnumerator enumerator = notifier .SubscribeAsync(cts.Token) .GetAsyncEnumerator(cts.Token); Assert.True(await enumerator.MoveNextAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(1))); Assert.Same(first, enumerator.Current); await cts.CancelAsync(); } [Fact] public async Task Publish_FansOutToAllSubscribers() { GalaxyDeployNotifier notifier = new(); using CancellationTokenSource cts = new(); await using IAsyncEnumerator a = notifier .SubscribeAsync(cts.Token) .GetAsyncEnumerator(cts.Token); await using IAsyncEnumerator b = notifier .SubscribeAsync(cts.Token) .GetAsyncEnumerator(cts.Token); GalaxyDeployEventInfo info = new(1, DateTimeOffset.UtcNow, null, 0, 0); notifier.Publish(info); Assert.True(await a.MoveNextAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(1))); Assert.True(await b.MoveNextAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(1))); Assert.Same(info, a.Current); Assert.Same(info, b.Current); await cts.CancelAsync(); } [Fact] public void Latest_TracksMostRecentPublish() { GalaxyDeployNotifier notifier = new(); Assert.Null(notifier.Latest); GalaxyDeployEventInfo first = new(1, DateTimeOffset.UtcNow, null, 0, 0); GalaxyDeployEventInfo second = new(2, DateTimeOffset.UtcNow, null, 0, 0); notifier.Publish(first); notifier.Publish(second); Assert.Same(second, notifier.Latest); } }