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]);
}