using Grpc.Core; using ZB.MOM.WW.MxGateway.Contracts.Proto.Galaxy; namespace ZB.MOM.WW.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(); /// Gets the queue of discover hierarchy replies; dequeued in FIFO order. 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); } /// Records BrowseChildren RPC calls made by the client. public List<(BrowseChildrenRequest Request, CallOptions CallOptions)> BrowseChildrenCalls { get; } = []; /// Default reply returned from BrowseChildren when the queue is empty. public BrowseChildrenReply BrowseChildrenReply { get; set; } = new(); /// Queue of replies returned from BrowseChildren; dequeued in FIFO order. public Queue BrowseChildrenReplies { get; } = new(); /// Queue of exceptions to throw from BrowseChildren; dequeued in FIFO order. public Queue BrowseChildrenExceptions { get; } = new(); /// /// Records the request and either throws a queued exception or returns the configured reply. /// /// The BrowseChildrenRequest to process. /// Call options specifying RPC behavior. public Task BrowseChildrenAsync( BrowseChildrenRequest request, CallOptions callOptions) { BrowseChildrenCalls.Add((request, callOptions)); if (BrowseChildrenExceptions.TryDequeue(out Exception? exception)) { return Task.FromException(exception); } return Task.FromResult( BrowseChildrenReplies.TryDequeue(out BrowseChildrenReply? reply) ? reply : BrowseChildrenReply); } /// /// 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; } } }