using Opc.Ua; using ZB.MOM.WW.LmxOpcUa.Client.Shared; using ZB.MOM.WW.LmxOpcUa.Client.Shared.Models; using BrowseResult = ZB.MOM.WW.LmxOpcUa.Client.Shared.Models.BrowseResult; using ConnectionState = ZB.MOM.WW.LmxOpcUa.Client.Shared.Models.ConnectionState; namespace ZB.MOM.WW.LmxOpcUa.Client.UI.Tests.Fakes; /// /// Fake IOpcUaClientService for unit testing. /// public sealed class FakeOpcUaClientService : IOpcUaClientService { // Configurable responses public ConnectionInfo? ConnectResult { get; set; } public Exception? ConnectException { get; set; } public IReadOnlyList BrowseResults { get; set; } = Array.Empty(); public Exception? BrowseException { get; set; } public DataValue ReadResult { get; set; } = new DataValue(new Variant(42), StatusCodes.Good, DateTime.UtcNow, DateTime.UtcNow); public Exception? ReadException { get; set; } public StatusCode WriteResult { get; set; } = StatusCodes.Good; public Exception? WriteException { get; set; } public RedundancyInfo? RedundancyResult { get; set; } public Exception? RedundancyException { get; set; } public IReadOnlyList HistoryRawResult { get; set; } = Array.Empty(); public IReadOnlyList HistoryAggregateResult { get; set; } = Array.Empty(); public Exception? HistoryException { get; set; } // Call tracking public int ConnectCallCount { get; private set; } public int DisconnectCallCount { get; private set; } public int ReadCallCount { get; private set; } public int WriteCallCount { get; private set; } public int BrowseCallCount { get; private set; } public int SubscribeCallCount { get; private set; } public int UnsubscribeCallCount { get; private set; } public int SubscribeAlarmsCallCount { get; private set; } public int UnsubscribeAlarmsCallCount { get; private set; } public int RequestConditionRefreshCallCount { get; private set; } public int HistoryReadRawCallCount { get; private set; } public int HistoryReadAggregateCallCount { get; private set; } public int GetRedundancyInfoCallCount { get; private set; } public ConnectionSettings? LastConnectionSettings { get; private set; } public NodeId? LastReadNodeId { get; private set; } public NodeId? LastWriteNodeId { get; private set; } public object? LastWriteValue { get; private set; } public NodeId? LastBrowseParentNodeId { get; private set; } public NodeId? LastSubscribeNodeId { get; private set; } public int LastSubscribeIntervalMs { get; private set; } public NodeId? LastUnsubscribeNodeId { get; private set; } public AggregateType? LastAggregateType { get; private set; } public bool IsConnected { get; set; } public ConnectionInfo? CurrentConnectionInfo { get; set; } public event EventHandler? DataChanged; public event EventHandler? AlarmEvent; public event EventHandler? ConnectionStateChanged; public Task ConnectAsync(ConnectionSettings settings, CancellationToken ct = default) { ConnectCallCount++; LastConnectionSettings = settings; if (ConnectException != null) throw ConnectException; IsConnected = true; CurrentConnectionInfo = ConnectResult; return Task.FromResult(ConnectResult!); } public Task DisconnectAsync(CancellationToken ct = default) { DisconnectCallCount++; IsConnected = false; CurrentConnectionInfo = null; return Task.CompletedTask; } public Task ReadValueAsync(NodeId nodeId, CancellationToken ct = default) { ReadCallCount++; LastReadNodeId = nodeId; if (ReadException != null) throw ReadException; return Task.FromResult(ReadResult); } public Task WriteValueAsync(NodeId nodeId, object value, CancellationToken ct = default) { WriteCallCount++; LastWriteNodeId = nodeId; LastWriteValue = value; if (WriteException != null) throw WriteException; return Task.FromResult(WriteResult); } public Task> BrowseAsync(NodeId? parentNodeId = null, CancellationToken ct = default) { BrowseCallCount++; LastBrowseParentNodeId = parentNodeId; if (BrowseException != null) throw BrowseException; return Task.FromResult(BrowseResults); } public Task SubscribeAsync(NodeId nodeId, int intervalMs = 1000, CancellationToken ct = default) { SubscribeCallCount++; LastSubscribeNodeId = nodeId; LastSubscribeIntervalMs = intervalMs; return Task.CompletedTask; } public Task UnsubscribeAsync(NodeId nodeId, CancellationToken ct = default) { UnsubscribeCallCount++; LastUnsubscribeNodeId = nodeId; return Task.CompletedTask; } public Task SubscribeAlarmsAsync(NodeId? sourceNodeId = null, int intervalMs = 1000, CancellationToken ct = default) { SubscribeAlarmsCallCount++; return Task.CompletedTask; } public Task UnsubscribeAlarmsAsync(CancellationToken ct = default) { UnsubscribeAlarmsCallCount++; return Task.CompletedTask; } public Task RequestConditionRefreshAsync(CancellationToken ct = default) { RequestConditionRefreshCallCount++; return Task.CompletedTask; } public Task> HistoryReadRawAsync(NodeId nodeId, DateTime startTime, DateTime endTime, int maxValues = 1000, CancellationToken ct = default) { HistoryReadRawCallCount++; if (HistoryException != null) throw HistoryException; return Task.FromResult(HistoryRawResult); } public Task> HistoryReadAggregateAsync(NodeId nodeId, DateTime startTime, DateTime endTime, AggregateType aggregate, double intervalMs = 3600000, CancellationToken ct = default) { HistoryReadAggregateCallCount++; LastAggregateType = aggregate; if (HistoryException != null) throw HistoryException; return Task.FromResult(HistoryAggregateResult); } public Task GetRedundancyInfoAsync(CancellationToken ct = default) { GetRedundancyInfoCallCount++; if (RedundancyException != null) throw RedundancyException; return Task.FromResult(RedundancyResult!); } // Methods to raise events from tests public void RaiseDataChanged(DataChangedEventArgs args) => DataChanged?.Invoke(this, args); public void RaiseAlarmEvent(AlarmEventArgs args) => AlarmEvent?.Invoke(this, args); public void RaiseConnectionStateChanged(ConnectionStateChangedEventArgs args) => ConnectionStateChanged?.Invoke(this, args); public void Dispose() { // No-op for testing } }