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