using EventSubscriber.Application; namespace EventSubscriber.Tests; /// In-memory stand-ins for the projection store and notification log, so the /// projector's behaviour is exercised without Postgres (hand-written stubs, the repo's /// convention — no mocking library). /// A fake ACL client standing in for the register records Objecten holds: a test seeds a /// record per object URL, and the call count proves a rebuild does not re-read through the ACL. internal sealed class FakeAclClient : IAclClient { public Dictionary Records { get; } = []; public int CallCount { get; private set; } public Task GetRegisterRecordAsync(Uri objectUrl, CancellationToken ct = default) { CallCount++; return Task.FromResult(Records.TryGetValue(objectUrl.ToString(), out var record) ? record : null); } } internal sealed class InMemoryNotificationLog : INotificationLog { private readonly Dictionary _byKey = []; public Task TryRecordAsync(RecordedNotification notification, CancellationToken ct = default) => Task.FromResult(_byKey.TryAdd(notification.Key, notification)); public Task> AllAsync(CancellationToken ct = default) => Task.FromResult>([.. _byKey.Values]); } internal sealed class InMemoryProjectionStore : IProjectionStore { private readonly Dictionary _byId = []; /// How many times a write was attempted — lets a test prove a deduped delivery /// never reaches the store (an idempotent upsert hides the difference in row count alone). public int UpsertCount { get; private set; } public Task UpsertAsync(RegisterEntry entry, CancellationToken ct = default) { UpsertCount++; _byId[entry.Id] = entry; return Task.CompletedTask; } public Task ClearAsync(CancellationToken ct = default) { _byId.Clear(); return Task.CompletedTask; } public Task> AllAsync(CancellationToken ct = default) => Task.FromResult>([.. _byId.Values]); }