using Grpc.Core; using MxGateway.Contracts.Proto.Galaxy; namespace MxGateway.Client.Tests; /// /// Fake Galaxy Repository client transport for testing. /// internal sealed class FakeGalaxyRepositoryTransport(MxGatewayClientOptions options) : IGalaxyRepositoryClientTransport { /// /// Gets the gateway client options. /// public MxGatewayClientOptions Options { get; } = options; /// /// Gets the raw gRPC client; always null for the fake. /// public GalaxyRepository.GalaxyRepositoryClient? RawClient => null; /// /// Gets the list of TestConnection RPC calls made by the client. /// public List<(TestConnectionRequest Request, CallOptions CallOptions)> TestConnectionCalls { get; } = []; /// /// Gets the list of GetLastDeployTime RPC calls made by the client. /// public List<(GetLastDeployTimeRequest Request, CallOptions CallOptions)> GetLastDeployTimeCalls { get; } = []; /// /// Gets the list of DiscoverHierarchy RPC calls made by the client. /// public List<(DiscoverHierarchyRequest Request, CallOptions CallOptions)> DiscoverHierarchyCalls { get; } = []; /// /// Gets or sets the reply to return from TestConnection; defaults to successful response. /// public TestConnectionReply TestConnectionReply { get; set; } = new() { Ok = true }; /// /// Gets or sets the reply to return from GetLastDeployTime; defaults to no deploy time present. /// public GetLastDeployTimeReply GetLastDeployTimeReply { get; set; } = new() { Present = false }; /// /// Gets or sets the reply to return from DiscoverHierarchy; defaults to empty response. /// public DiscoverHierarchyReply DiscoverHierarchyReply { get; set; } = new(); public Queue DiscoverHierarchyReplies { get; } = new(); /// /// Gets the queue of exceptions to throw from TestConnection; dequeued in FIFO order. /// public Queue TestConnectionExceptions { get; } = new(); /// /// Gets the queue of exceptions to throw from GetLastDeployTime; dequeued in FIFO order. /// public Queue GetLastDeployTimeExceptions { get; } = new(); /// /// Gets the queue of exceptions to throw from DiscoverHierarchy; dequeued in FIFO order. /// public Queue DiscoverHierarchyExceptions { get; } = new(); /// /// Records the request and either throws a queued exception or returns the configured reply. /// /// The TestConnectionRequest to process. /// Call options specifying RPC behavior. public Task TestConnectionAsync( TestConnectionRequest request, CallOptions callOptions) { TestConnectionCalls.Add((request, callOptions)); if (TestConnectionExceptions.TryDequeue(out Exception? exception)) { throw exception; } return Task.FromResult(TestConnectionReply); } /// /// Records the request and either throws a queued exception or returns the configured reply. /// /// The GetLastDeployTimeRequest to process. /// Call options specifying RPC behavior. public Task GetLastDeployTimeAsync( GetLastDeployTimeRequest request, CallOptions callOptions) { GetLastDeployTimeCalls.Add((request, callOptions)); if (GetLastDeployTimeExceptions.TryDequeue(out Exception? exception)) { throw exception; } return Task.FromResult(GetLastDeployTimeReply); } /// /// Records the request and either throws a queued exception or returns the configured reply. /// /// The DiscoverHierarchyRequest to process. /// Call options specifying RPC behavior. public Task DiscoverHierarchyAsync( DiscoverHierarchyRequest request, CallOptions callOptions) { DiscoverHierarchyCalls.Add((request, callOptions)); if (DiscoverHierarchyExceptions.TryDequeue(out Exception? exception)) { throw exception; } return Task.FromResult( DiscoverHierarchyReplies.TryDequeue(out DiscoverHierarchyReply? reply) ? reply : DiscoverHierarchyReply); } /// /// Gets the list of WatchDeployEvents RPC calls made by the client. /// public List<(WatchDeployEventsRequest Request, CallOptions CallOptions)> WatchDeployEventsCalls { get; } = []; /// /// Gets or sets the list of events to stream from WatchDeployEvents. /// public List WatchDeployEvents { get; } = []; /// /// Gets or sets the exception to throw from WatchDeployEvents, if any. /// public Exception? WatchDeployEventsException { get; set; } /// /// When set, awaited before each event yield so tests can observe cancellation /// mid-stream. Receives the call's cancellation token. /// public Func? WatchDeployEventsBeforeYield { get; set; } /// /// Records the request and streams events, checking for queued exceptions and calling WatchDeployEventsBeforeYield before each event. /// /// The WatchDeployEventsRequest to process. /// Call options specifying RPC behavior. public async IAsyncEnumerable WatchDeployEventsAsync( WatchDeployEventsRequest request, CallOptions callOptions) { WatchDeployEventsCalls.Add((request, callOptions)); if (WatchDeployEventsException is not null) { throw WatchDeployEventsException; } foreach (DeployEvent deployEvent in WatchDeployEvents) { if (WatchDeployEventsBeforeYield is not null) { await WatchDeployEventsBeforeYield(callOptions.CancellationToken).ConfigureAwait(false); } callOptions.CancellationToken.ThrowIfCancellationRequested(); yield return deployEvent; } } }