using FluentAssertions; using Microsoft.Extensions.Logging.Abstractions; using SatelliteProvider.Common.DTO; using SatelliteProvider.Services; namespace SatelliteProvider.Tests; public class RegionRequestQueueTests { private static RegionRequest BuildRequest() => new() { Id = Guid.NewGuid(), Latitude = 47.461747, Longitude = 37.647063, SizeMeters = 200, ZoomLevel = 18, StitchTiles = false }; [Fact] public async Task EnqueueAsync_RespectsCapacity_WritesUpToCapacityWithoutBlocking_RS04() { const int capacity = 10; var queue = new RegionRequestQueue(capacity, NullLogger.Instance); for (var i = 0; i < capacity; i++) { await queue.EnqueueAsync(BuildRequest()); } queue.Count.Should().Be(capacity); } [Fact] public async Task EnqueueAsync_BlocksWhenAtCapacity_UntilDequeue_RL02() { const int capacity = 2; var queue = new RegionRequestQueue(capacity, NullLogger.Instance); await queue.EnqueueAsync(BuildRequest()); await queue.EnqueueAsync(BuildRequest()); var overflow = queue.EnqueueAsync(BuildRequest()).AsTask(); var completedFirst = await Task.WhenAny(overflow, Task.Delay(150)); completedFirst.Should().NotBeSameAs(overflow, "overflow enqueue must wait while queue is full"); var dequeued = await queue.DequeueAsync(); dequeued.Should().NotBeNull(); await overflow.WaitAsync(TimeSpan.FromSeconds(1)); queue.Count.Should().Be(capacity); } [Fact] public async Task EnqueueAsync_HonorsCancellation_WhenFull() { var queue = new RegionRequestQueue(1, NullLogger.Instance); await queue.EnqueueAsync(BuildRequest()); using var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(150)); Func act = async () => await queue.EnqueueAsync(BuildRequest(), cts.Token); await act.Should().ThrowAsync(); } [Fact] public async Task DequeueAsync_ReturnsItemsInFifoOrder() { var queue = new RegionRequestQueue(8, NullLogger.Instance); var first = BuildRequest(); var second = BuildRequest(); await queue.EnqueueAsync(first); await queue.EnqueueAsync(second); var dequeued1 = await queue.DequeueAsync(); var dequeued2 = await queue.DequeueAsync(); dequeued1!.Id.Should().Be(first.Id); dequeued2!.Id.Should().Be(second.Id); queue.Count.Should().Be(0); } }