using ZB.MOM.WW.CBDDC.Core.Network; using ZB.MOM.WW.CBDDC.Core.Sync; namespace ZB.MOM.WW.CBDDC.Core.Tests; public class OfflineQueueTests { /// /// Verifies that enqueuing beyond capacity drops the oldest operation. /// [Fact] public async Task Enqueue_WhenQueueIsFull_DropsOldestOperation() { var queue = new OfflineQueue(CreateConfigProvider(maxQueueSize: 2)); await queue.Enqueue(CreateOperation("1")); await queue.Enqueue(CreateOperation("2")); await queue.Enqueue(CreateOperation("3")); var flushed = new List(); (int successful, int failed) = await queue.FlushAsync(op => { flushed.Add(op.Key); return Task.CompletedTask; }); successful.ShouldBe(2); failed.ShouldBe(0); flushed.ShouldBe(["2", "3"]); } /// /// Verifies that flush continues when an executor throws and returns the failure count. /// [Fact] public async Task FlushAsync_WhenExecutorThrows_ContinuesAndReturnsFailureCount() { var queue = new OfflineQueue(CreateConfigProvider(maxQueueSize: 10)); await queue.Enqueue(CreateOperation("1")); await queue.Enqueue(CreateOperation("2")); (int successful, int failed) = await queue.FlushAsync(op => { if (op.Key == "1") throw new InvalidOperationException("boom"); return Task.CompletedTask; }); successful.ShouldBe(1); failed.ShouldBe(1); queue.Count.ShouldBe(0); } /// /// Verifies that clear removes all queued operations. /// [Fact] public async Task Clear_RemovesAllQueuedOperations() { var queue = new OfflineQueue(CreateConfigProvider(maxQueueSize: 10)); await queue.Enqueue(CreateOperation("1")); await queue.Enqueue(CreateOperation("2")); queue.Count.ShouldBe(2); await queue.Clear(); queue.Count.ShouldBe(0); (int successful, int failed) = await queue.FlushAsync(_ => Task.CompletedTask); successful.ShouldBe(0); failed.ShouldBe(0); } private static PendingOperation CreateOperation(string key) { return new PendingOperation { Type = "upsert", Collection = "users", Key = key, Data = new { Value = key }, QueuedAt = DateTime.UtcNow }; } private static IPeerNodeConfigurationProvider CreateConfigProvider(int maxQueueSize) { var configProvider = Substitute.For(); configProvider.GetConfiguration().Returns(new PeerNodeConfiguration { MaxQueueSize = maxQueueSize }); return configProvider; } }