144 lines
4.4 KiB
C#
144 lines
4.4 KiB
C#
using KronaStaffTerminal.Services;
|
|
|
|
namespace KronaStaffTerminal.Tests.Mocks;
|
|
|
|
public sealed class MockFingerprintScanner : IFingerprintScanner
|
|
{
|
|
private readonly List<ScannerDeviceInfo> _devices = new();
|
|
private readonly Dictionary<int, string> _loadedTemplates = new();
|
|
private int _registrationTargetId;
|
|
private int _registrationStep;
|
|
|
|
public ScannerState State { get; private set; } = ScannerState.Disconnected;
|
|
public int DeviceCount => _devices.Count;
|
|
public int ReaderIndex { get; private set; } = -1;
|
|
public IReadOnlyList<ScannerDeviceInfo> DiscoveredDevices => _devices;
|
|
public bool IsConnected => State == ScannerState.Connected || State == ScannerState.Busy;
|
|
public int SkippedTemplateCount { get; set; } = 0;
|
|
public int ConnectCallCount { get; private set; } = 0;
|
|
|
|
public event Action<int, int>? FingerRecognized;
|
|
public event Action<int>? RegistrationProgress;
|
|
public event Action<int, string>? RegistrationCompleted;
|
|
public event Action<string>? StatusChanged;
|
|
public event Action<ScannerState, string>? StateChanged;
|
|
public event Action? ConnectionLost;
|
|
public event Action? RegistrationCancelled;
|
|
|
|
public MockFingerprintScanner()
|
|
{
|
|
// Default with 1 virtual SLK20R
|
|
_devices.Add(new ScannerDeviceInfo(0, "SLK20R-Virtual", "ZK-VIRT-001", "SLK20R [ZK-VIRT-001]"));
|
|
}
|
|
|
|
public void AddVirtualDevice(int index, string model, string serial)
|
|
{
|
|
_devices.Add(new ScannerDeviceInfo(index, model, serial, $"{model} [{serial}]"));
|
|
}
|
|
|
|
public void ClearDevices()
|
|
{
|
|
_devices.Clear();
|
|
}
|
|
|
|
public IReadOnlyList<ScannerDeviceInfo> DiscoverDevices()
|
|
{
|
|
return _devices;
|
|
}
|
|
|
|
public void Connect(int readerIndex, IEnumerable<(int FingerprintId, string Template)> templates)
|
|
{
|
|
ConnectCallCount++;
|
|
if (_devices.Count == 0)
|
|
{
|
|
State = ScannerState.DriverError;
|
|
StateChanged?.Invoke(ScannerState.DriverError, "No devices found");
|
|
return;
|
|
}
|
|
|
|
ReaderIndex = readerIndex;
|
|
_loadedTemplates.Clear();
|
|
foreach (var (id, tpl) in templates)
|
|
{
|
|
_loadedTemplates[id] = tpl;
|
|
}
|
|
|
|
State = ScannerState.Connected;
|
|
StateChanged?.Invoke(ScannerState.Connected, "Scanner ready");
|
|
StatusChanged?.Invoke("Scanner ready");
|
|
}
|
|
|
|
public void Disconnect()
|
|
{
|
|
State = ScannerState.Disconnected;
|
|
ReaderIndex = -1;
|
|
_loadedTemplates.Clear();
|
|
StateChanged?.Invoke(ScannerState.Disconnected, "Scanner disconnected");
|
|
StatusChanged?.Invoke("Scanner disconnected");
|
|
}
|
|
|
|
public void BeginRegistration(int fingerprintId)
|
|
{
|
|
_registrationTargetId = fingerprintId;
|
|
_registrationStep = 0;
|
|
State = ScannerState.Busy;
|
|
StateChanged?.Invoke(ScannerState.Busy, "Enrolling finger");
|
|
}
|
|
|
|
public void CancelRegistration()
|
|
{
|
|
_registrationTargetId = 0;
|
|
_registrationStep = 0;
|
|
if (State == ScannerState.Busy)
|
|
{
|
|
State = ScannerState.Connected;
|
|
StateChanged?.Invoke(ScannerState.Connected, "Registration cancelled");
|
|
}
|
|
RegistrationCancelled?.Invoke();
|
|
}
|
|
|
|
public void SimulateFingerScan(int fingerprintId, int score = 85)
|
|
{
|
|
if (State != ScannerState.Connected)
|
|
{
|
|
return;
|
|
}
|
|
|
|
FingerRecognized?.Invoke(fingerprintId, score);
|
|
}
|
|
|
|
public void SimulateEnrollmentSample(string? finalTemplate = null)
|
|
{
|
|
if (State != ScannerState.Busy) return;
|
|
|
|
_registrationStep++;
|
|
RegistrationProgress?.Invoke(_registrationStep);
|
|
|
|
if (_registrationStep >= 3)
|
|
{
|
|
string tpl = finalTemplate ?? Convert.ToBase64String(new byte[512]);
|
|
_loadedTemplates[_registrationTargetId] = tpl;
|
|
State = ScannerState.Connected;
|
|
StateChanged?.Invoke(ScannerState.Connected, "Registration complete");
|
|
RegistrationCompleted?.Invoke(_registrationTargetId, tpl);
|
|
}
|
|
}
|
|
|
|
public void SimulateDisconnect()
|
|
{
|
|
State = ScannerState.Disconnected;
|
|
StateChanged?.Invoke(ScannerState.Disconnected, "Device unplugged");
|
|
ConnectionLost?.Invoke();
|
|
}
|
|
|
|
public void SimulateReconnect()
|
|
{
|
|
State = ScannerState.Connected;
|
|
StateChanged?.Invoke(ScannerState.Connected, "Device reconnected");
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Disconnect();
|
|
}
|
|
}
|