using System.Threading.Channels;
using DodoSSH.Client.Api;
using DodoSSH.Contracts;
namespace DodoSSH.Client.App.Tests;
///
/// A server's push channel, driven by a test rather than by a socket.
///
///
/// The real VaultEventStream is a reconnection policy wrapped round a WebSocket, and none of
/// that is what the shell's behaviour depends on: what the shell does with a notice is the same
/// whether it arrived over a healthy socket, after four reconnections, or from this. Driving it by
/// hand is what makes "the loop synchronised because it was told to, not because a minute passed" a
/// test that finishes in milliseconds and cannot flake.
///
internal sealed class FakeVaultEventStream : IVaultEventStream
{
private readonly Channel notices = Channel.CreateUnbounded();
///
public bool IsConnected => true;
/// How many times the shell has waited on this. Proves the loop is watching at all.
internal int Reads { get; private set; }
/// Delivers a notice, as a server would.
internal void Push(Guid vaultId, long sequence = 1) =>
notices.Writer.TryWrite(
new VaultEvent(VaultEventKinds.VaultChanged, vaultId, sequence));
/// Delivers the notice that says the caller's vault list has changed.
internal void PushAccessChanged() =>
notices.Writer.TryWrite(new VaultEvent(VaultEventKinds.VaultsChanged));
///
public ValueTask ReadAsync(CancellationToken cancellationToken)
{
Reads++;
return notices.Reader.ReadAsync(cancellationToken);
}
///
public bool TryRead(out VaultEvent notice) => notices.Reader.TryRead(out notice!);
///
public void Dispose() => notices.Writer.TryComplete();
}