using System.Text.Json.Nodes; using System.Threading.Channels; using backend.Realtime; namespace backend.tests; public class ScriptedRealtimeUpstream : IRealtimeUpstream { private readonly Channel _toRelay = Channel.CreateUnbounded(new UnboundedChannelOptions { SingleReader = true }); private readonly Channel _fromRelay = Channel.CreateUnbounded(new UnboundedChannelOptions { SingleWriter = true }); public IList Sent { get; } = new List(); public Task SendJsonAsync(JsonObject envelope, CancellationToken ct) { Sent.Add(envelope); return _fromRelay.Writer.WriteAsync(envelope, ct).AsTask(); } public async Task ReceiveJsonAsync(CancellationToken ct) { try { return await _toRelay.Reader.ReadAsync(ct); } catch (ChannelClosedException) { return null; } } public void Push(JsonObject evt) => _toRelay.Writer.TryWrite(evt); public void CloseUpstream() => _toRelay.Writer.TryComplete(); public async Task WaitForSentAsync(string type, CancellationToken ct) { await foreach (var item in _fromRelay.Reader.ReadAllAsync(ct)) { if ((string?)item["type"] == type) return item; } throw new TimeoutException($"never saw outbound {type}"); } public ValueTask DisposeAsync() { _toRelay.Writer.TryComplete(); _fromRelay.Writer.TryComplete(); return ValueTask.CompletedTask; } }