using ZB.MOM.WW.Secrets.Abstractions;
using ZB.MOM.WW.Secrets.Replicator.SqlServer;
using ZB.MOM.WW.Secrets.Sqlite;
namespace ZB.MOM.WW.Secrets.Replicator.SqlServer.Tests.Fakes;
///
/// An backed by a real SQLite store, standing in for the shared
/// SQL-Server hub in offline convergence tests.
///
///
/// Deliberately backed by a real store rather than a dictionary: the behaviour under test is
/// last-writer-wins convergence, which lives in ApplyReplicatedAsync. A hand-rolled fake would
/// be re-implementing the very logic the tests exist to check, and would happily agree with a broken
/// reconciler. The live SQL-Server tests then confirm the T-SQL store behaves the same way.
///
/// The SQLite store standing in for the hub database.
public sealed class SqliteBackedHub(SqliteSecretStore store) : ISecretReplicationHub
{
/// Number of times the sweep asked this hub for rows — asserts the fetch was skipped.
public int GetManyCallCount { get; private set; }
///
public Task> GetManifestAsync(CancellationToken ct) =>
store.GetManifestAsync(ct);
///
public async Task> GetManyAsync(
IReadOnlyList names, CancellationToken ct)
{
GetManyCallCount++;
var rows = new List(names.Count);
foreach (SecretName name in names)
{
StoredSecret? row = await store.GetAsync(name, ct);
if (row is not null)
{
rows.Add(row);
}
}
return rows;
}
///
/// A row name the hub refuses on push, as SQL Server refuses a name longer than its
/// NVARCHAR(450) column ("String or binary data would be truncated").
///
public string? RejectPushOf { get; set; }
///
public Task ApplyReplicatedAsync(StoredSecret row, CancellationToken ct) =>
row.Name.Value == RejectPushOf
? throw new InvalidOperationException("String or binary data would be truncated.")
: store.ApplyReplicatedAsync(row, ct);
}