using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using NSubstitute; using NUnit.Framework; using Plugin.BLE.Abstractions.Contracts; using ShareeBike.Services.BluetoothLock; using ShareeBike.Services.BluetoothLock.BLE; using ShareeBike.Services.BluetoothLock.Exception; using ShareeBike.Services.BluetoothLock.Tdo; namespace LockIt.BLE.Tests.Services.BluetoothLock.BLE { public class TestLockItServiceBase { [Test] public async Task TestCheckReconnect_EmptyList() { var disconnectedDevice = Substitute.For(); disconnectedDevice.GetDeviceState().Returns(DeviceState.Disconnected); var devices = new List { disconnectedDevice }; var locksInfo = new List(); await LockItServiceBase.CheckReconnect( devices, locksInfo, TimeSpan.FromSeconds(0)); await disconnectedDevice.DidNotReceive().ReconnectAsync(Arg.Any(), Arg.Any()); } [Test] public async Task TestCheckReconnect_NoMatchingIdEntry() { var disconnectedDevice = Substitute.For(); disconnectedDevice.GetDeviceState().Returns(DeviceState.Disconnected); disconnectedDevice.Name.Returns("ISHAREIT+334"); disconnectedDevice.Guid.Returns(new Guid("00000000-0000-0000-0000-000000000001")); var devices = new List { disconnectedDevice }; var locksInfo = new List { new LockInfoAuthTdo.Builder { Id = 992, Guid = new Guid("00000000-0000-0000-0000-000000000002"), K_seed = new byte[] { 2 }, K_u = new byte[] { 3 } }.Build() }; await LockItServiceBase.CheckReconnect( devices, locksInfo, TimeSpan.FromSeconds(0)); await disconnectedDevice.DidNotReceive().ReconnectAsync(Arg.Any(), Arg.Any()); } [Test] public async Task TestCheckReconnect() { var disconnectedDevice = Substitute.For(); disconnectedDevice.GetDeviceState().Returns(DeviceState.Disconnected); disconnectedDevice.Name.Returns("ISHAREIT+992"); disconnectedDevice.Guid.Returns(new Guid("00000000-0000-0000-0000-000000000001")); var devices = new List { disconnectedDevice }; var locksInfo = new List { new LockInfoAuthTdo.Builder { Id = 992, Guid = new Guid("00000000-0000-0000-0000-000000000002"), K_seed = new byte[] { 2 }, K_u = new byte[] { 3 } }.Build() }; await LockItServiceBase.CheckReconnect( devices, locksInfo, TimeSpan.FromSeconds(0)); await disconnectedDevice.Received().ReconnectAsync(Arg.Any(), Arg.Any()); } [Test] public void TestConnect_Connected_InvalidArgs() { var device = Substitute.For(); var adapter = Substitute.For(); var cipher = Substitute.For(); var exception = Assert.Throws( () => { var lockIt = LockItEventBased.Authenticate(device, null, adapter, cipher).Result; }, "If connected no auth is requied."); Assert.That(exception.InnerExceptions.Count > 0); Assert.That(exception.InnerExceptions[0], Is.InstanceOf()); } [Test] public void TestConnect_Connected() { var device = Substitute.For(); var adapter = Substitute.For(); var cipher = Substitute.For(); var auth = Substitute.For(); var lockControl = Substitute.For(); var authTdo = new LockInfoAuthTdo.Builder { Id = 12, K_seed = new byte[] { (byte)'i', (byte)'V', (byte)'F', (byte)'m', (byte)'u', (byte)'T', (byte)'n', (byte)'K', (byte)'q', (byte)'E', (byte)'Y', (byte)'h', (byte)'m', (byte)'T', (byte)'l', (byte)'e' }, K_u = new byte[16] }.Build(); device.State.Returns(Plugin.BLE.Abstractions.DeviceState.Connected); device.GetServiceAsync(Arg.Any(), Arg.Any()).Returns(Task.FromResult(lockControl)); lockControl.GetCharacteristicAsync(Arg.Any()).Returns(Task.FromResult(auth)); auth.WriteAsync(Arg.Any()).Returns(Task.FromResult(LockItBase.ERRORCODE_SUCCESS)); // Write COPRI seed to lock auth.ReadAsync(Arg.Any()).Returns(Task.FromResult((new byte[8], LockItBase.ERRORCODE_SUCCESS))); // Read lock seed cipher.Decrypt(Arg.Any(), Arg.Any()).Returns(new byte[3]); cipher.Encrypt(Arg.Any(), Arg.Any()).Returns(new byte[16]); auth.WriteAsync(Arg.Any()).Returns(Task.FromResult(LockItBase.ERRORCODE_SUCCESS)); // Write COPRI seed to lock device.Name.Returns("Origin"); Assert.That( LockItEventBased.Authenticate(device, authTdo, adapter, cipher).Result.Name, Is.EqualTo("Origin"), "If connected no auth is requied."); } [Test] public void TestAuth() { var authTdo = new LockInfoAuthTdo.Builder { Id = 12, K_seed = new byte[] { (byte)'c', (byte)'b', (byte)'z', (byte)'b', (byte)'y', (byte)'I', (byte)'q', (byte)'j', (byte)'v', (byte)'L', (byte)'V', (byte)'I', (byte)'t', (byte)'C', (byte)'B', (byte)'I' }, K_u = new byte[16] }.Build(); var device = Substitute.For(); var adapter = Substitute.For(); var cipher = Substitute.For(); // Use factory to create LockIt-object. var exception = Assert.Throws( () => { var lockIt = LockItEventBased.Authenticate(device, authTdo, adapter, cipher).Result; }, "If connected no auth is requied."); Assert.That(exception.InnerExceptions.Count > 0); Assert.That(exception.InnerExceptions[0], Is.InstanceOf()); } } }