diff --git a/tests/RustPlusBot.Features.Map.Tests/Hosting/MapRefreshTests.cs b/tests/RustPlusBot.Features.Map.Tests/Hosting/MapRefreshTests.cs index 0ba1011..8cf4841 100644 --- a/tests/RustPlusBot.Features.Map.Tests/Hosting/MapRefreshTests.cs +++ b/tests/RustPlusBot.Features.Map.Tests/Hosting/MapRefreshTests.cs @@ -148,15 +148,20 @@ public async Task A_server_that_is_no_longer_connected_loses_its_cached_base_map await h.PublishUntilAsync(() => new ConnectionStatusChangedEvent(Guild, Server, false, true), h.WhenStatusHandled); + // Priming republishes until the first post lands, so repaints queued before the disconnect are + // still being drained and keep posting. A post count cannot tell those from a repaint made + // after the disconnect; a second fetch can only come from one that found the cache empty. await h.PublishUntilAsync(() => new MapMarkersChangedEvent(Guild, Server, null, [], [], []), - h.PostCountReachesAsync(2)); + h.BaseMapFetchesReachAsync(2)); } finally { await h.Service.StopAsync(CancellationToken.None); } - Assert.Equal(2, h.BaseMapFetches); + // Not exactly two: the disconnect is republished too, and each copy evicts the tile again. + Assert.True(h.BaseMapFetches >= 2, + $"the cached base map survived the disconnect (fetches: {h.BaseMapFetches})"); } [Fact] @@ -392,6 +397,8 @@ private sealed class FakeBaseMapSource(byte[]? jpeg, Action onFetch) : IBaseMapS private sealed class Harness : IDisposable { + private readonly List<(int Count, TaskCompletionSource Tcs)> _baseMapFetchTargets = []; + private readonly ConcurrentDictionary> _channelPostTargets = new(); @@ -498,6 +505,12 @@ public static Harness Create( public Task PostCountReachesAsync(int count) => WaitForCountAsync(_postTargets, count, Posts); + /// Completes once the base map has been fetched times. + /// The fetch count to wait for. + /// A task that completes when the base map has been fetched that many times. + public Task BaseMapFetchesReachAsync(int count) => + WaitForCountAsync(_baseMapFetchTargets, count, BaseMapFetches); + /// How many posts one channel has received so far. /// The channel to count. /// The post count for that channel. @@ -565,7 +578,8 @@ private static IRigState Rigs() return rigs; } - private void OnBaseMapFetch() => Interlocked.Increment(ref _baseMapFetches); + private void OnBaseMapFetch() => + ReleaseReached(_baseMapFetchTargets, Interlocked.Increment(ref _baseMapFetches)); private Task OnPostAsync(ulong channelId) {