using Opc.Ua; using ZB.MOM.WW.LmxOpcUa.Client.Shared.Adapters; namespace ZB.MOM.WW.LmxOpcUa.Client.Shared.Tests.Fakes; internal sealed class FakeSubscriptionAdapter : ISubscriptionAdapter { private readonly Dictionary? DataCallback, Action? EventCallback )> _items = new(); private uint _nextHandle = 100; public bool Deleted { get; private set; } public bool ConditionRefreshCalled { get; private set; } public bool ThrowOnConditionRefresh { get; set; } public int AddDataChangeCount { get; private set; } public int AddEventCount { get; private set; } public int RemoveCount { get; private set; } /// /// Gets the handles of all active items. /// public IReadOnlyCollection ActiveHandles => _items.Keys.ToList(); public uint SubscriptionId { get; set; } = 42; public Task AddDataChangeMonitoredItemAsync(NodeId nodeId, int samplingIntervalMs, Action onDataChange, CancellationToken ct) { AddDataChangeCount++; var handle = _nextHandle++; _items[handle] = (nodeId, onDataChange, null); return Task.FromResult(handle); } public Task RemoveMonitoredItemAsync(uint clientHandle, CancellationToken ct) { RemoveCount++; _items.Remove(clientHandle); return Task.CompletedTask; } public Task AddEventMonitoredItemAsync(NodeId nodeId, int samplingIntervalMs, EventFilter filter, Action onEvent, CancellationToken ct) { AddEventCount++; var handle = _nextHandle++; _items[handle] = (nodeId, null, onEvent); return Task.FromResult(handle); } public Task ConditionRefreshAsync(CancellationToken ct) { ConditionRefreshCalled = true; if (ThrowOnConditionRefresh) throw new InvalidOperationException("Condition refresh not supported"); return Task.CompletedTask; } public Task DeleteAsync(CancellationToken ct) { Deleted = true; _items.Clear(); return Task.CompletedTask; } public void Dispose() { _items.Clear(); } /// /// Simulates a data change notification for testing. /// public void SimulateDataChange(uint handle, DataValue value) { if (_items.TryGetValue(handle, out var item) && item.DataCallback != null) item.DataCallback(item.NodeId.ToString(), value); } /// /// Simulates an event notification for testing. /// public void SimulateEvent(uint handle, EventFieldList eventFields) { if (_items.TryGetValue(handle, out var item) && item.EventCallback != null) item.EventCallback(eventFields); } }