mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-05-11 12:17:28 +02:00
Legacy testing lib added..
This commit is contained in:
parent
0167fc321f
commit
47ed05837e
118 changed files with 17505 additions and 0 deletions
20
TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfo.cs
Normal file
20
TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfo.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Model.Bike.BC;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BC
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikeInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestCtorCopyNull()
|
||||
{
|
||||
Assert.Throws<System.ArgumentException>(
|
||||
() => new BikeInfo(null),
|
||||
"Verify that no unspecific reference not set to... exception is thrown");
|
||||
}
|
||||
}
|
||||
}
|
128
TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfoMutable.cs
Normal file
128
TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfoMutable.cs
Normal file
|
@ -0,0 +1,128 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Bikes.Bike;
|
||||
using TINK.Model.State;
|
||||
|
||||
using IBikeInfo = TINK.Model.Bike.BC.IBikeInfo;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBikeInfoMutable
|
||||
{
|
||||
private class BikeInfoMutable : TINK.Model.Bike.BC.BikeInfoMutable
|
||||
{
|
||||
public BikeInfoMutable(
|
||||
string id,
|
||||
bool isDemo = false,
|
||||
IEnumerable<string> group = null,
|
||||
WheelType? wheelType = null,
|
||||
TypeOfBike? typeOfBike = null,
|
||||
string description = null,
|
||||
string currentStationId = null,
|
||||
Uri operatorUri = null,
|
||||
TariffDescription tariffDescription = null,
|
||||
Func<DateTime> dateTimeProvider = null,
|
||||
IStateInfo stateInfo = null) : base(id, isDemo, group, wheelType, typeOfBike, description, currentStationId, operatorUri, tariffDescription, dateTimeProvider, stateInfo)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oBikeInfo = new BikeInfoMutable("17");
|
||||
Assert.AreEqual("17", l_oBikeInfo.Id);
|
||||
Assert.IsNull(l_oBikeInfo.CurrentStation);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual(null, l_oBikeInfo.WheelType);
|
||||
Assert.AreEqual(null, l_oBikeInfo.TypeOfBike);
|
||||
|
||||
l_oBikeInfo = new BikeInfoMutable("22", false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Cargo, "Test description", "23");
|
||||
Assert.AreEqual("22", l_oBikeInfo.Id);
|
||||
Assert.IsFalse(l_oBikeInfo.IsDemo);
|
||||
Assert.AreEqual("23", l_oBikeInfo.CurrentStation);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual(WheelType.Trike, l_oBikeInfo.WheelType);
|
||||
Assert.AreEqual(TypeOfBike.Cargo, l_oBikeInfo.TypeOfBike);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstructCopy()
|
||||
{
|
||||
// State Booked
|
||||
var l_oBikeInfoMock = MockRepository.GenerateStub<IBikeInfo>();
|
||||
var l_oStateInfoMock = MockRepository.GenerateStub<IStateInfo>();
|
||||
|
||||
l_oBikeInfoMock.Stub(x => x.Id).Return("22");
|
||||
l_oBikeInfoMock.Stub(x => x.TypeOfBike).Return(TypeOfBike.Cargo);
|
||||
l_oBikeInfoMock.Stub(x => x.WheelType).Return(WheelType.Trike);
|
||||
l_oBikeInfoMock.Stub(x => x.CurrentStation).Return("23");
|
||||
l_oBikeInfoMock.Stub(x => x.State).Return(l_oStateInfoMock);
|
||||
l_oStateInfoMock.Stub(x => x.Value).Return(InUseStateEnum.Booked);
|
||||
l_oStateInfoMock.Stub(x => x.From).Return(new System.DateTime(2018, 01, 03));
|
||||
l_oStateInfoMock.Stub(x => x.MailAddress).Return("a@b");
|
||||
l_oStateInfoMock.Stub(x => x.Code).Return("234");
|
||||
|
||||
var l_oBikeInfo = new TINK.Model.Bike.BC.BikeInfoMutable(l_oBikeInfoMock);
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual("22", l_oBikeInfo.Id);
|
||||
Assert.AreEqual("23", l_oBikeInfo.CurrentStation);
|
||||
Assert.AreEqual(WheelType.Trike, l_oBikeInfo.WheelType);
|
||||
Assert.AreEqual(TypeOfBike.Cargo, l_oBikeInfo.TypeOfBike);
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual(new System.DateTime(2018, 01, 03), l_oBikeInfo.State.From);
|
||||
Assert.AreEqual("a@b", l_oBikeInfo.State.MailAddress);
|
||||
|
||||
// State Reserved
|
||||
l_oBikeInfoMock = MockRepository.GenerateStub<IBikeInfo>();
|
||||
l_oStateInfoMock = MockRepository.GenerateStub<IStateInfo>();
|
||||
|
||||
l_oBikeInfoMock.Stub(x => x.Id).Return("22");
|
||||
l_oBikeInfoMock.Stub(x => x.TypeOfBike).Return(TypeOfBike.Cargo);
|
||||
l_oBikeInfoMock.Stub(x => x.WheelType).Return(WheelType.Trike);
|
||||
l_oBikeInfoMock.Stub(x => x.CurrentStation).Return("23");
|
||||
l_oBikeInfoMock.Stub(x => x.State).Return(l_oStateInfoMock);
|
||||
l_oStateInfoMock.Stub(x => x.Value).Return(InUseStateEnum.Reserved);
|
||||
l_oStateInfoMock.Stub(x => x.From).Return(new System.DateTime(2018, 01, 03));
|
||||
l_oStateInfoMock.Stub(x => x.MailAddress).Return("a@b");
|
||||
l_oStateInfoMock.Stub(x => x.Code).Return("234");
|
||||
|
||||
l_oBikeInfo = new TINK.Model.Bike.BC.BikeInfoMutable(l_oBikeInfoMock);
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual("22", l_oBikeInfo.Id);
|
||||
Assert.AreEqual("23", l_oBikeInfo.CurrentStation);
|
||||
Assert.AreEqual(WheelType.Trike, l_oBikeInfo.WheelType);
|
||||
Assert.AreEqual(TypeOfBike.Cargo, l_oBikeInfo.TypeOfBike);
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual(new System.DateTime(2018, 01, 03), l_oBikeInfo.State.From);
|
||||
Assert.AreEqual("a@b", l_oBikeInfo.State.MailAddress);
|
||||
|
||||
// State Disposable
|
||||
l_oBikeInfoMock = MockRepository.GenerateStub<IBikeInfo>();
|
||||
l_oStateInfoMock = MockRepository.GenerateStub<IStateInfo>();
|
||||
|
||||
l_oBikeInfoMock.Stub(x => x.Id).Return("22");
|
||||
l_oBikeInfoMock.Stub(x => x.TypeOfBike).Return(TypeOfBike.Cargo);
|
||||
l_oBikeInfoMock.Stub(x => x.WheelType).Return(WheelType.Trike);
|
||||
l_oBikeInfoMock.Stub(x => x.CurrentStation).Return("23");
|
||||
l_oBikeInfoMock.Stub(x => x.State).Return(l_oStateInfoMock);
|
||||
l_oStateInfoMock.Stub(x => x.Value).Return(InUseStateEnum.Disposable);
|
||||
|
||||
l_oBikeInfo = new TINK.Model.Bike.BC.BikeInfoMutable(l_oBikeInfoMock);
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeInfo.State.Value);
|
||||
Assert.AreEqual("22", l_oBikeInfo.Id);
|
||||
Assert.AreEqual("23", l_oBikeInfo.CurrentStation);
|
||||
Assert.AreEqual(WheelType.Trike, l_oBikeInfo.WheelType);
|
||||
Assert.AreEqual(TypeOfBike.Cargo, l_oBikeInfo.TypeOfBike);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeInfo.State.Value);
|
||||
Assert.IsNull(l_oBikeInfo.State.From);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.State;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBikeInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCtorCopyNull()
|
||||
{
|
||||
Assert.Throws<System.ArgumentException>(
|
||||
() => new BikeInfo(null, null),
|
||||
"Verify that no unspecific reference not set to... exception is thrown");
|
||||
|
||||
Assert.Throws<System.ArgumentException>(
|
||||
() => new BikeInfo(new TINK.Model.Bike.BC.BikeInfo(12,1), null),
|
||||
"Verify that no unspecific reference not set to... exception is thrown");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorAvailable()
|
||||
{
|
||||
Assert.AreEqual (12,new BikeInfo(12, 13).Id);
|
||||
Assert.AreEqual(13, new BikeInfo(12, 13).CurrentStation);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, new BikeInfo(12, 13).State.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorRequested()
|
||||
{
|
||||
Assert.AreEqual(12, new BikeInfo(12, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", 13, dateTimeProvider: () => new DateTime(2019, 1, 1)).Id);
|
||||
Assert.AreEqual(112, new BikeInfo(12, 112, new Guid(), null, null, null, new DateTime(2020,1,1), "a@b", 13, dateTimeProvider: () => new DateTime(2019, 1, 1)).LockInfo.Id);
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, new BikeInfo(12, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", 13, dateTimeProvider: () => new DateTime(2019, 1, 1)).State.Value);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorBooked()
|
||||
{
|
||||
Assert.AreEqual(12, new BikeInfo(12, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", 13).Id);
|
||||
Assert.AreEqual(112, new BikeInfo(12, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", 13).LockInfo.Id);
|
||||
Assert.AreEqual(InUseStateEnum.Booked, new BikeInfo(12, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", 13).State.Value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
LockingState.Unknown,
|
||||
new LockInfo.Builder { Id = 123 }.Build().State);
|
||||
|
||||
Assert.AreEqual(
|
||||
123,
|
||||
new LockInfo.Builder { Id = 123 }.Build().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEquals()
|
||||
{
|
||||
Assert.IsTrue(new LockInfo.Builder {
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed}.Build() == new LockInfo.Builder {
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse()
|
||||
{
|
||||
Assert.IsFalse(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 3,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build());
|
||||
|
||||
Assert.IsFalse(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("1000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build());
|
||||
|
||||
Assert.IsFalse(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 5, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build());
|
||||
|
||||
Assert.IsFalse(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 9, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build());
|
||||
|
||||
Assert.IsFalse(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 11, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build());
|
||||
|
||||
Assert.IsFalse(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Open
|
||||
}.Build());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestLockInfoHelper
|
||||
{
|
||||
[Test]
|
||||
public void TestUpdateById_State()
|
||||
{
|
||||
var locksInfo = new List<LockInfo> {
|
||||
new LockInfo.Builder { Id = 12, Seed = new byte[] { 3, 5 }, UserKey = new byte[] {2, 1 }, State = LockingState.Unknown }.Build(),
|
||||
new LockInfo.Builder { Id = 14, Seed = new byte[] { 3, 1 }, UserKey = new byte[] {2, 7 }, State = LockingState.Open }.Build(),
|
||||
new LockInfo.Builder { Id = 3, Seed = new byte[] { 1, 5 }, UserKey = new byte[] {2, 9 }, State = LockingState.Closed }.Build(),
|
||||
};
|
||||
|
||||
var locksInfoTdo = new List<LockInfoTdo> {
|
||||
new LockInfoTdo.Builder { Id =14, State = LockitLockingState.Closed}.Build()
|
||||
};
|
||||
|
||||
var resultList = locksInfo.UpdateById(locksInfoTdo);
|
||||
|
||||
var result = resultList.FirstOrDefault(x => x.Id == 14);
|
||||
Assert.NotNull(result, "Target element was removed.");
|
||||
Assert.AreEqual(LockingState.Closed, result.State);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpdateById_Guid()
|
||||
{
|
||||
var locksInfo = new List<LockInfo> {
|
||||
new LockInfo.Builder { Id = 12, Seed = new byte[] { 3, 5 }, UserKey = new byte[] {2, 1 }, State = LockingState.Unknown }.Build(),
|
||||
new LockInfo.Builder { Id = 14, Seed = new byte[] { 3, 1 }, UserKey = new byte[] {2, 7 }, State = LockingState.Open }.Build(),
|
||||
new LockInfo.Builder { Id = 3, Seed = new byte[] { 1, 5 }, UserKey = new byte[] {2, 9 }, State = LockingState.Closed }.Build(),
|
||||
};
|
||||
|
||||
var locksInfoTdo = new List<LockInfoTdo> {
|
||||
new LockInfoTdo.Builder { Id =14, Guid = new System.Guid("00000000-0000-0000-0000-e57e6b9aee16"), State = LockitLockingState.Open}.Build()
|
||||
};
|
||||
|
||||
var resultList = locksInfo.UpdateById(locksInfoTdo);
|
||||
|
||||
var result = resultList.FirstOrDefault(x => x.Id == 14);
|
||||
Assert.NotNull(result, "Target element was removed.");
|
||||
Assert.AreEqual(new Guid("00000000-0000-0000-0000-e57e6b9aee16"), result.Guid);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestLockInfoMutable
|
||||
{
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(1, new Guid(), new byte[] { 1, 2, 3 }, new byte[] { 1, 23 }, new byte[] { 1, 12 }, LockingState.Closed);
|
||||
|
||||
Assert.AreEqual(1, lockInfo.Id);
|
||||
Assert.AreEqual(new Guid(), lockInfo.Guid);
|
||||
Assert.IsTrue((new byte[] { 1, 2, 3 }).SequenceEqual(lockInfo.UserKey));
|
||||
Assert.IsTrue((new byte[] { 1, 23 }).SequenceEqual(lockInfo.AdminKey));
|
||||
Assert.IsTrue((new byte[] { 1, 12 }).SequenceEqual(lockInfo.Seed));
|
||||
Assert.AreEqual(LockingState.Closed, lockInfo.State);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSetGuid()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(1, new Guid(), new byte[] { 1, 2, 3 }, new byte[] { 1, 23 }, new byte[] { 1, 12 }, LockingState.Closed);
|
||||
|
||||
lockInfo.Guid = new Guid("00000000-0000-0000-0000-e57e6b9aee16");
|
||||
Assert.AreEqual(new Guid("00000000-0000-0000-0000-e57e6b9aee16"), lockInfo.Guid);
|
||||
}
|
||||
}
|
||||
}
|
49
TestTINKLib/Fixtures/ObjectTests/Bike/TestBike.cs
Normal file
49
TestTINKLib/Fixtures/ObjectTests/Bike/TestBike.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using NUnit.Framework;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike
|
||||
{
|
||||
using TINK.Model.Bike;
|
||||
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBike
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oBike = new Bike(43);
|
||||
Assert.AreEqual(43, l_oBike.Id);
|
||||
Assert.AreEqual(null, l_oBike.TypeOfBike);
|
||||
Assert.AreEqual(null, l_oBike.WheelType);
|
||||
|
||||
l_oBike = new Bike(43, WheelType.Mono, TypeOfBike.Cargo);
|
||||
|
||||
Assert.AreEqual(43, l_oBike.Id);
|
||||
Assert.AreEqual(TypeOfBike.Cargo, l_oBike.TypeOfBike);
|
||||
Assert.AreEqual(WheelType.Mono, l_oBike.WheelType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCompare()
|
||||
{
|
||||
var l_oBike1 = new Bike(43);
|
||||
Assert.AreEqual(43, l_oBike1.Id);
|
||||
Assert.AreEqual(null, l_oBike1.TypeOfBike);
|
||||
Assert.AreEqual(null, l_oBike1.WheelType);
|
||||
|
||||
var l_oBike2 = new Bike(42, WheelType.Two, TypeOfBike.Allround);
|
||||
Assert.IsFalse(l_oBike1 == l_oBike2);
|
||||
|
||||
l_oBike2 = new Bike(43, WheelType.Mono, TypeOfBike.Allround);
|
||||
Assert.IsFalse(l_oBike1 == l_oBike2);
|
||||
|
||||
l_oBike2 = new Bike(43, WheelType.Two, TypeOfBike.Cargo);
|
||||
Assert.IsFalse(l_oBike1 == l_oBike2);
|
||||
|
||||
l_oBike2 = new Bike(43, null, null);
|
||||
Assert.IsTrue(l_oBike1 == l_oBike2);
|
||||
}
|
||||
}
|
||||
}
|
25
TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollection.cs
Normal file
25
TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollection.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.Bike;
|
||||
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikeCollection
|
||||
{
|
||||
/// <summary> Tests the member.</summary>
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oColl = new BikeCollection();
|
||||
|
||||
Assert.AreEqual(0, l_oColl.Count);
|
||||
Assert.IsNull(l_oColl.GetById(1));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bike;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikeCollectionFilter
|
||||
{
|
||||
[Test]
|
||||
public void TestGetAtStation()
|
||||
{
|
||||
var coll = new BikeCollection(
|
||||
new Dictionary<int, TINK.Model.Bike.BC.BikeInfo>
|
||||
{
|
||||
{3, new TINK.Model.Bike.BC.BikeInfo(7, 3 /* Stadion id */) },
|
||||
{7, new TINK.Model.Bike.BC.BikeInfo(8, 12 /* Stadion id */) },
|
||||
{12, new TINK.Model.Bike.BC.BikeInfo(33, 12 /* Stadion id */) }
|
||||
});
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
BikeCollectionFilter.GetAtStation(null, 12).Count);
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
coll.GetAtStation(null).Count);
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
coll.GetAtStation(22).Count);
|
||||
|
||||
Assert.AreEqual(
|
||||
1,
|
||||
coll.GetAtStation(3).Count);
|
||||
|
||||
Assert.AreEqual(
|
||||
2,
|
||||
coll.GetAtStation(12).Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetLockIt()
|
||||
{
|
||||
var coll = new BikeCollection(
|
||||
new Dictionary<int, TINK.Model.Bike.BC.BikeInfo>
|
||||
{
|
||||
{7, new TINK.Model.Bike.BC.BikeInfo(8, 12 /* Stadion id */) },
|
||||
{12, new TINK.Model.Bike.BC.BikeInfo(33, 12 /* Stadion id */) }
|
||||
});
|
||||
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
coll.GetLockIt().Count);
|
||||
|
||||
coll = new BikeCollection(
|
||||
new Dictionary<int, TINK.Model.Bike.BC.BikeInfo>
|
||||
{
|
||||
{7, new TINK.Model.Bike.BC.BikeInfo(8, 12 /* Stadion id */) },
|
||||
{11, new TINK.Model.Bike.BluetoothLock.BikeInfo(33, 12 /* Stadion id */) },
|
||||
{12, new TINK.Model.Bike.BC.BikeInfo(33, 12 /* Stadion id */) }
|
||||
});
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
BikeCollectionFilter.GetLockIt(null).Count);
|
||||
|
||||
Assert.AreEqual(
|
||||
1,
|
||||
coll.GetLockIt().Count);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.State;
|
||||
|
||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||
using BikeInfoMutable = TINK.Model.Bike.BC.BikeInfoMutable;
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikeCollectionMutable
|
||||
{
|
||||
/// <summary> Tests the member.</summary>
|
||||
[Test]
|
||||
public void TestAdd()
|
||||
{
|
||||
var l_oColl = new BikeCollectionMutable();
|
||||
|
||||
l_oColl.Add(new BikeInfoMutable(57, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Allround));
|
||||
|
||||
Assert.Throws<Exception>(() => l_oColl.Add(new BikeInfoMutable(57, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Cargo)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpdate_Null()
|
||||
{
|
||||
var l_oBikeRequested = new BikeInfoMutable(20, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Allround);
|
||||
l_oBikeRequested.State.Load(new StateInfo(() => DateTime.Now, DateTime.Now, "john@long", "1234"));
|
||||
|
||||
var l_oBikeColl = new BikeCollectionMutable
|
||||
{
|
||||
new BikeInfoMutable(63, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Allround),
|
||||
new BikeInfoMutable(57, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Cargo),
|
||||
l_oBikeRequested,
|
||||
};
|
||||
|
||||
// Verify initial state
|
||||
Assert.NotNull(l_oBikeColl.GetById("63"));
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeColl.GetById("57").State.Value);
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oBikeColl.GetById("20").State.Value);
|
||||
Assert.Null(l_oBikeColl.GetById("33"));
|
||||
|
||||
l_oBikeColl.Update(null);
|
||||
|
||||
// Verify modified state
|
||||
Assert.Null(l_oBikeColl.GetById("63"));
|
||||
Assert.Null(l_oBikeColl.GetById("57"));
|
||||
Assert.Null(l_oBikeColl.GetById("20"));
|
||||
Assert.Null(l_oBikeColl.GetById("33"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpdate()
|
||||
{
|
||||
var l_oBikeRequested = new BikeInfoMutable(20, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Allround);
|
||||
l_oBikeRequested.State.Load(new StateInfo(() => DateTime.Now, DateTime.Now, "john@long", "1234"));
|
||||
|
||||
var l_oBikeColl = new BikeCollectionMutable
|
||||
{
|
||||
new BikeInfoMutable(63, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Allround),
|
||||
new BikeInfoMutable(57, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Cargo),
|
||||
l_oBikeRequested,
|
||||
};
|
||||
|
||||
// Verify initial state
|
||||
Assert.NotNull(l_oBikeColl.GetById("63")); // Will be removed
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeColl.GetById("57").State.Value); // Will be requested
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oBikeColl.GetById("20").State.Value); // Will be booked
|
||||
Assert.Null(l_oBikeColl.GetById("33")); //
|
||||
|
||||
var l_oBikeResponse = new List<BikeInfo>
|
||||
{
|
||||
new BikeInfo("57", false, new [] { "TINK" }, WheelType.Trike, TypeOfBike.Allround, "Test description", 7, DateTime.Now, "john@long,", "1234"),
|
||||
new BikeInfo("20", false, new [] {"TINK" }, WheelType.Trike, TypeOfBike.Allround, "Test description", 7, DateTime.Now, "john@long,", "1234"),
|
||||
new BikeInfo("33", 7, false, new [] {"TINK" }, WheelType.Trike, TypeOfBike.Allround),
|
||||
};
|
||||
|
||||
l_oBikeColl.Update(l_oBikeResponse);
|
||||
|
||||
// Verify modified state
|
||||
Assert.Null(l_oBikeColl.GetById("63"));
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oBikeColl.GetById("57").State.Value);
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oBikeColl.GetById("20").State.Value);
|
||||
Assert.NotNull(l_oBikeColl.GetById("33"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Model.Bike;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using TINK.Model.State;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BikeInfoMutable = TINK.Model.Bike.BC.BikeInfoMutable;
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikeCollectionSerializeJSON
|
||||
{
|
||||
[Test, Ignore("Disabled because serialization does no more work due to inheritance since commit ec14b93b.")]
|
||||
public void Test_SerializeJSON()
|
||||
{
|
||||
var l_oCollSource = new BikeCollectionMutable
|
||||
{
|
||||
new BikeInfoMutable(57, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Allround)
|
||||
};
|
||||
|
||||
// Verify prerequisites.
|
||||
Assert.AreEqual(1, l_oCollSource.Count);
|
||||
Assert.AreEqual(57, l_oCollSource[0].Id);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oCollSource[0].State.Value);
|
||||
Assert.IsNull(l_oCollSource[0].State.MailAddress);
|
||||
Assert.IsNull(l_oCollSource[0].State.Code);
|
||||
Assert.IsNull(l_oCollSource[0].State.From);
|
||||
|
||||
// Serialize object and verify json
|
||||
var l_oDetected = JsonConvert.SerializeObject(l_oCollSource, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
const string EXPECTED = @"
|
||||
[
|
||||
{
|
||||
""Id"": 57,
|
||||
""CurrentStation"": null,
|
||||
""WheelType"": 1,
|
||||
""TypeOfBike"": 0,
|
||||
""State"": {
|
||||
""StateInfoObject"": {
|
||||
""$type"": ""TINK.Model.State.StateAvailableInfo, TINKLib""
|
||||
}
|
||||
}
|
||||
}
|
||||
]";
|
||||
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED),
|
||||
TestHelper.PrepareXmlForStringCompare(l_oDetected));
|
||||
|
||||
// Deserialize object.
|
||||
var l_oBikeCollectionTarget = JsonConvert.DeserializeObject<BikeCollectionMutable>(l_oDetected, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
|
||||
// Verify state.
|
||||
Assert.AreEqual(1, l_oBikeCollectionTarget.Count);
|
||||
Assert.AreEqual(57, l_oBikeCollectionTarget[0].Id);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeCollectionTarget[0].State.Value);
|
||||
Assert.IsNull(l_oBikeCollectionTarget[0].State.MailAddress);
|
||||
Assert.IsNull(l_oBikeCollectionTarget[0].State.Code);
|
||||
Assert.IsNull(l_oBikeCollectionTarget[0].State.From);
|
||||
}
|
||||
}
|
||||
}
|
67
TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeMutable.cs
Normal file
67
TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeMutable.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.State;
|
||||
|
||||
using BikeInfoMutable = TINK.Model.Bike.BC.BikeInfoMutable;
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
class TestBikeMutable
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable(
|
||||
42,
|
||||
false,
|
||||
new List<string> { "TINK" },
|
||||
WheelType.Two,
|
||||
TypeOfBike.Cargo);
|
||||
|
||||
Assert.AreEqual(42, l_oBike.Id);
|
||||
Assert.IsFalse(l_oBike.IsDemo);
|
||||
Assert.AreEqual(WheelType.Two, l_oBike.WheelType);
|
||||
Assert.AreEqual(TypeOfBike.Cargo, l_oBike.TypeOfBike);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBike.State.Value);
|
||||
Assert.IsNull(l_oBike.CurrentStation);
|
||||
|
||||
l_oBike = new BikeInfoMutable(
|
||||
17,
|
||||
true,
|
||||
new List<string> { "TINK" },
|
||||
WheelType.Mono,
|
||||
TypeOfBike.Allround,
|
||||
"Test description",
|
||||
1);
|
||||
|
||||
Assert.AreEqual(17, l_oBike.Id);
|
||||
Assert.IsTrue(l_oBike.IsDemo);
|
||||
Assert.AreEqual(WheelType.Mono, l_oBike.WheelType);
|
||||
Assert.AreEqual(TypeOfBike.Allround, l_oBike.TypeOfBike);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBike.State.Value);
|
||||
Assert.AreEqual(1, l_oBike.CurrentStation);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestToString()
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable(3, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, p_oDateTimeProvider: () => new DateTime(1970, 1, 1));
|
||||
|
||||
Assert.AreEqual(
|
||||
"Id=3, wheel(s)=Two, type=Cargo, demo=False, state=Disposable, location=On the road.",
|
||||
l_oBike.ToString());
|
||||
|
||||
l_oBike = new BikeInfoMutable(3, true, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Allround, "Test description", 5, p_oDateTimeProvider: () => new DateTime(1970, 1, 1));
|
||||
Assert.AreEqual(
|
||||
"Id=3, wheel(s)=Trike, type=Allround, demo=True, state=Disposable, location=Station 5.",
|
||||
l_oBike.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.State;
|
||||
|
||||
using BikeInfoMutable = TINK.Model.Bike.BC.BikeInfoMutable;
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikeSerializeJSON
|
||||
{
|
||||
[Test, Ignore("Disabled because serialization does no more work due to inheritance since commit ec14b93b.")]
|
||||
public void TestConstruct_SerializeJSON_Disposable()
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oBikeSource = new BikeInfoMutable(3, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, p_oDateTimeProvider: () => new DateTime(1970, 1, 1));
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeSource.State.Value);
|
||||
Assert.IsNull(l_oBikeSource.State.MailAddress);
|
||||
Assert.IsNull(l_oBikeSource.State.Code);
|
||||
Assert.IsNull(l_oBikeSource.State.From);
|
||||
|
||||
// Serialize object and verify.
|
||||
var l_oDetected = JsonConvert.SerializeObject(l_oBikeSource, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
const string EXPECTED = @"
|
||||
{
|
||||
""Id"": 3,
|
||||
""CurrentStation"": null,
|
||||
""WheelType"": 1,
|
||||
""TypeOfBike"": 1,
|
||||
""State"": {
|
||||
""StateInfoObject"": {
|
||||
""$type"": ""TINK.Model.State.StateAvailableInfo, TINKLib""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED),
|
||||
TestHelper.PrepareXmlForStringCompare(l_oDetected));
|
||||
|
||||
// Deserialize object.
|
||||
var l_oBikeTarget = JsonConvert.DeserializeObject<BikeInfoMutable>(l_oDetected, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
|
||||
// Verify state.
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBikeTarget.State.Value);
|
||||
Assert.IsNull(l_oBikeTarget.State.MailAddress);
|
||||
Assert.IsNull(l_oBikeTarget.State.Code);
|
||||
Assert.IsNull(l_oBikeTarget.State.From);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestBikesAvailableResponse
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserializeStationEmpty()
|
||||
{
|
||||
// Response for bike 231 is a real world answer.
|
||||
var l_oBikes = JsonConvert.DeserializeObject<BikesAvailableResponse>(@"
|
||||
{
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
""231"" : {
|
||||
""bike"" : ""231"",
|
||||
""description"" : ""Stadtrad"",
|
||||
""system"" : ""BC"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""station"" : """",
|
||||
""state"" : ""available"",
|
||||
""gps"" : { ""latitude"": ""9.1594501"", ""longitude"": ""47.6749928"" }
|
||||
}
|
||||
},
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""authcookie"" : """",
|
||||
""response_state"" : ""OK""
|
||||
}
|
||||
");
|
||||
|
||||
Assert.IsNull(l_oBikes.bikes[231].station);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserializeStationInfoMissing()
|
||||
{
|
||||
// Response for bike 231 might not be real world answer.
|
||||
var l_oBikes = JsonConvert.DeserializeObject<BikesAvailableResponse>(@"
|
||||
{
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
""231"" : {
|
||||
""bike"" : ""231"",
|
||||
""description"" : ""Stadtrad"",
|
||||
""system"" : ""BC"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""state"" : ""available"",
|
||||
""gps"" : { ""latitude"": ""9.1594501"", ""longitude"": ""47.6749928"" }
|
||||
}
|
||||
},
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""authcookie"" : """",
|
||||
""response_state"" : ""OK""
|
||||
}
|
||||
");
|
||||
|
||||
Assert.IsNull(l_oBikes.bikes[231].station);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib.Fixtures.Bike
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestStateBookedInfoSerializeJSON
|
||||
{
|
||||
[Test]
|
||||
public void TestSerializeJSON()
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oInfoSource = new StateOccupiedInfo(
|
||||
new DateTime(2017, 09, 20, 23, 05, 0),
|
||||
"Heinz@mueller",
|
||||
"17 xxb");
|
||||
|
||||
// Serialize object and verify.
|
||||
var l_oDetected = JsonConvert.SerializeObject(l_oInfoSource);
|
||||
const string EXPECTED = @"
|
||||
{
|
||||
""From"":""2017 - 09 - 20T23: 05:00"",
|
||||
""MailAddress"":""Heinz@mueller"",
|
||||
""Code"":""17 xxb""
|
||||
}";
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED.Replace("\n", string.Empty).Replace("\r", string.Empty)),
|
||||
TestHelper.PrepareXmlForStringCompare(l_oDetected.Replace("\n", string.Empty).Replace("\r", string.Empty)));
|
||||
|
||||
// Deserialize object and verify.
|
||||
var l_oInfoTarget = JsonConvert.DeserializeObject<StateOccupiedInfo>(l_oDetected);
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oInfoTarget.Value);
|
||||
Assert.AreEqual("Heinz@mueller", l_oInfoTarget.MailAddress);
|
||||
Assert.AreEqual("17 xxb", l_oInfoTarget.Code);
|
||||
Assert.AreEqual(new DateTime(2017, 9, 20, 23, 5, 0), l_oInfoTarget.From);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace UITest.Fixtures.Connector
|
||||
{
|
||||
/// <summary>
|
||||
/// Object which manages calls to copri.
|
||||
/// </summary>
|
||||
public class CopriCallsHttpsReference
|
||||
{
|
||||
/// <summary> Logs user in. </summary>
|
||||
/// <param name="copriHost">Host to connect to. </param>
|
||||
/// <param name="merchantId">Id of the merchant.</param>
|
||||
/// <param name="mailAddress">Mailaddress of user to log in.</param>
|
||||
/// <param name="password">Password to log in.</param>
|
||||
/// <param name="deviceId">Id specifying user and hardware.</param>
|
||||
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
||||
public static AuthorizationResponse DoAuthorizeCall(
|
||||
string copriHost,
|
||||
string merchantId,
|
||||
string mailAddress,
|
||||
string password,
|
||||
string deviceId)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
|
||||
var l_oCommand = string.Format(
|
||||
"request=authorization&merchant_id={0}&user_id={1}&user_pw={2}&hw_id={3}",
|
||||
merchantId,
|
||||
mailAddress,
|
||||
password,
|
||||
deviceId);
|
||||
|
||||
/// Extract session cookie from response.
|
||||
|
||||
string response = string.Empty;
|
||||
|
||||
response = Post(l_oCommand, copriHost);
|
||||
|
||||
return JsonConvert.DeserializeObject<ResponseContainer<AuthorizationResponse>>(response)?.shareejson;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary> Logs user out. </summary>
|
||||
/// <param name="copriHost">Host to connect to. </param>
|
||||
/// <param name="merchantId">Id of the merchant.</param>
|
||||
/// <param name="sessionCookie"> Cookie which identifies user.</param>
|
||||
public static AuthorizationoutResponse DoAuthoutCall(
|
||||
string copriHost,
|
||||
string merchantId,
|
||||
string sessionCookie)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
|
||||
var l_oCommand = string.Format(
|
||||
"request=authout&authcookie={0}{1}",
|
||||
sessionCookie,
|
||||
merchantId);
|
||||
|
||||
string l_oLogoutResponse;
|
||||
|
||||
l_oLogoutResponse = Post(l_oCommand, copriHost);
|
||||
|
||||
/// Extract session cookie from response.
|
||||
return JsonConvert.DeserializeObject<ResponseContainer<AuthorizationoutResponse>>(l_oLogoutResponse)?.shareejson;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get list of stations from file.
|
||||
/// </summary>
|
||||
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
||||
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
||||
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
|
||||
/// <returns>List of files.</returns>
|
||||
public static StationsAllResponse GetStationsAllCall(
|
||||
string p_strCopriHost,
|
||||
string p_strMerchantId,
|
||||
string p_strCookie = null)
|
||||
{
|
||||
var l_oCommand = string.Format(
|
||||
"request=stations_all&authcookie={0}{1}",
|
||||
p_strCookie,
|
||||
p_strMerchantId);
|
||||
|
||||
#if !WINDOWS_UWP
|
||||
string l_oStationsAllResponse;
|
||||
|
||||
l_oStationsAllResponse = Post(l_oCommand, p_strCopriHost);
|
||||
|
||||
// Extract bikes from response.
|
||||
return JsonConvert.DeserializeObject<ResponseContainer<StationsAllResponse>>(l_oStationsAllResponse)?.shareejson;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of bikes from Copri.
|
||||
/// </summary>
|
||||
/// <param name="copriHost">URL of the copri host to connect to.</param>
|
||||
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
||||
/// <param name="p_strSessionCookie">Cookie to authenticate user.</param>
|
||||
/// <returns>Response holding list of bikes.</returns>
|
||||
public static BikesAvailableResponse GetBikesAvailableCall(
|
||||
string copriHost,
|
||||
string merchantId,
|
||||
string sessionCookie = null)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
string l_oCommand =
|
||||
$"request=bikes_available&system=all&authcookie={sessionCookie ?? string.Empty}{merchantId}";
|
||||
|
||||
string response;
|
||||
|
||||
response = Post(l_oCommand, copriHost);
|
||||
|
||||
// Extract bikes from response.
|
||||
return CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(response);
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of bikes reserved/ booked by acctive user from Copri.
|
||||
/// </summary>
|
||||
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
||||
/// <param name="p_strSessionCookie">Cookie to authenticate user.</param>
|
||||
/// <returns>Response holding list of bikes.</returns>
|
||||
public static BikesReservedOccupiedResponse GetBikesOccupiedCall(
|
||||
string copriHost,
|
||||
string merchantId,
|
||||
string sessionCookie)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
string l_oCommand = !string.IsNullOrEmpty(sessionCookie)
|
||||
? $"request=user_bikes_occupied&system=all&authcookie={sessionCookie}{merchantId}"
|
||||
: "request=bikes_available";
|
||||
|
||||
string l_oBikesOccupiedResponse;
|
||||
|
||||
l_oBikesOccupiedResponse = Post(l_oCommand, copriHost);
|
||||
|
||||
// Extract bikes from response.
|
||||
return CopriCallsStatic.DeserializeResponse<BikesReservedOccupiedResponse>(l_oBikesOccupiedResponse);
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets booking request response.
|
||||
/// </summary>
|
||||
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
||||
/// <param name="p_iBikeId">Id of the bike to book.</param>
|
||||
/// <param name="p_strSessionCookie">Cookie identifying the user.</param>
|
||||
/// <returns>Response on booking request.</returns>
|
||||
public static ReservationBookingResponse DoReserveCall(
|
||||
string copriHost,
|
||||
string p_strMerchantId,
|
||||
string p_iBikeId,
|
||||
string p_strSessionCookie)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
string l_oCommand = string.Format(
|
||||
"request=booking_request&bike={0}&authcookie={1}{2}",
|
||||
p_iBikeId,
|
||||
p_strSessionCookie,
|
||||
p_strMerchantId);
|
||||
|
||||
string l_oBikesAvaialbeResponse = Post(l_oCommand, copriHost);
|
||||
|
||||
// Extract bikes from response.
|
||||
return JsonConvert.DeserializeObject<ResponseContainer<ReservationBookingResponse>>(l_oBikesAvaialbeResponse)?.shareejson;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets canel booking request response.
|
||||
/// </summary>
|
||||
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
||||
/// <param name="p_iBikeId">Id of the bike to book.</param>
|
||||
/// <param name="p_strSessionCookie">Cookie of the logged in user.</param>
|
||||
/// <returns>Response on cancel booking request.</returns>
|
||||
public static ReservationCancelReturnResponse DoCancelReservationCall(
|
||||
string copriHost,
|
||||
string p_strMerchantId,
|
||||
string p_iBikeId,
|
||||
string p_strSessionCookie)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
string l_oCommand = string.Format(
|
||||
"request=booking_cancel&bike={0}&authcookie={1}{2}",
|
||||
p_iBikeId,
|
||||
p_strSessionCookie,
|
||||
p_strMerchantId);
|
||||
string l_oBikesAvaialbeResponse;
|
||||
|
||||
l_oBikesAvaialbeResponse = Post(l_oCommand, copriHost);
|
||||
|
||||
// Extract bikes from response.
|
||||
return JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(l_oBikesAvaialbeResponse)?.shareejson;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of bikes from Copri.
|
||||
/// </summary>
|
||||
/// <param name="p_strSessionCookie">Cookie to authenticate user.</param>
|
||||
/// <returns></returns>
|
||||
private static string Post(
|
||||
string p_strCommand,
|
||||
string p_strURL)
|
||||
{
|
||||
#if !WINDOWS_UWP
|
||||
var l_strHost = p_strURL;
|
||||
|
||||
// Returns a http request.
|
||||
var l_oRequest = WebRequest.Create(l_strHost);
|
||||
|
||||
l_oRequest.Method = "POST";
|
||||
l_oRequest.ContentType = "application/x-www-form-urlencoded";
|
||||
|
||||
byte[] l_oPostData = Encoding.UTF8.GetBytes(p_strCommand);
|
||||
|
||||
l_oRequest.ContentLength = l_oPostData.Length;
|
||||
|
||||
// Get the request stream.
|
||||
using (Stream l_oDataStream = l_oRequest.GetRequestStream())
|
||||
{
|
||||
// Write the data to the request stream.
|
||||
l_oDataStream.Write(l_oPostData, 0, l_oPostData.Length);
|
||||
}
|
||||
|
||||
// Get the response.
|
||||
var l_oResponse = l_oRequest.GetResponse() as HttpWebResponse;
|
||||
|
||||
if (l_oResponse == null)
|
||||
{
|
||||
throw new Exception(string.Format("Reserve request failed. Response form from server was not of expected type."));
|
||||
}
|
||||
|
||||
if (l_oResponse.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new CommunicationException(string.Format(
|
||||
"Posting request {0} failed. Expected status code is {1} but was {2}.",
|
||||
p_strCommand,
|
||||
HttpStatusCode.OK,
|
||||
l_oResponse.StatusCode));
|
||||
}
|
||||
|
||||
string responseFromServer = string.Empty;
|
||||
|
||||
// Get the request stream.
|
||||
using (Stream l_oDataStream = l_oResponse.GetResponseStream())
|
||||
using (StreamReader l_oReader = new StreamReader(l_oDataStream))
|
||||
{
|
||||
// Read the content.
|
||||
responseFromServer = l_oReader.ReadToEnd();
|
||||
|
||||
// Display the content.
|
||||
Console.WriteLine(responseFromServer);
|
||||
|
||||
// Clean up the streams.
|
||||
l_oResponse.Close();
|
||||
}
|
||||
|
||||
return responseFromServer;
|
||||
#else
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Exception
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestAuthcookieNotDefinedException
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"Can not test.\r\nDie Sitzung ist abgelaufen. Bitte neu anmelden.",
|
||||
(new AuthcookieNotDefinedException(
|
||||
"Can not test.",
|
||||
JsonConvert.DeserializeObject<ResponseBase>(@"{ ""response_state"" : ""Some inner error description""}"))).Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTestIsAuthcookieNotDefined_False()
|
||||
{
|
||||
var response = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(@"{ ""response_state"" : ""OK"" }");
|
||||
Assert.That(AuthcookieNotDefinedException.IsAuthcookieNotDefined(response, "Test context", out AuthcookieNotDefinedException exception),
|
||||
Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsAuthcookieNotDefined_TrueLegacy()
|
||||
{
|
||||
var response = JsonConvert.DeserializeObject<ResponseBase>($"{{ \"response_state\" : \"Failure 1003: authcookie not defined\" }}");
|
||||
Assert.That(AuthcookieNotDefinedException.IsAuthcookieNotDefined(response, "Test context", out AuthcookieNotDefinedException exception),
|
||||
Is.EqualTo(true));
|
||||
|
||||
Assert.That(exception, !Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsAuthcookieNotDefined_False()
|
||||
{
|
||||
var response = JsonConvert.DeserializeObject<ResponseBase>($"{{ \"response_state\" : \"Failure 1001: authcookie not defined\" }}");
|
||||
Assert.That(AuthcookieNotDefinedException.IsAuthcookieNotDefined(response, "Test context", out AuthcookieNotDefinedException exception),
|
||||
Is.EqualTo(true));
|
||||
|
||||
Assert.That(exception, !Is.Null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.Connector.Filter;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Filter
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestIntersectFilter
|
||||
{
|
||||
[Test]
|
||||
public void TestDoFilter_Null()
|
||||
{
|
||||
var filter = new IntersectGroupFilter(new List<string> { "Tonk" });
|
||||
|
||||
Assert.AreEqual(1, filter.DoFilter(null).Count());
|
||||
Assert.AreEqual(
|
||||
"Tonk",
|
||||
filter.DoFilter(null).ToArray()[0],
|
||||
"Do not apply filtering when null is passed as argement (null-filter).");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoFilter_Empty()
|
||||
{
|
||||
var filter = new IntersectGroupFilter(new List<string> { "Tonk" });
|
||||
|
||||
Assert.AreEqual(0, filter.DoFilter(new List<string>()).Count());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoFilter()
|
||||
{
|
||||
var filter = new IntersectGroupFilter(new List<string> { "Tonk", "Honk" });
|
||||
|
||||
Assert.AreEqual(1, filter.DoFilter(new List<string> { "Tonk", "Klonk" }).Count());
|
||||
Assert.AreEqual("Tonk", filter.DoFilter(new List<string> { "Tonk", "Klonk" }).ToArray()[0]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector.Filter;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Filter
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestNullFilter
|
||||
{
|
||||
[Test]
|
||||
public void TestDoFilter()
|
||||
{
|
||||
var filter = new NullGroupFilter();
|
||||
Assert.IsNull(filter.DoFilter(null));
|
||||
Assert.AreEqual(0, filter.DoFilter(new List<string>()).Count());
|
||||
Assert.AreEqual(1, filter.DoFilter(new List<string> { "Hello" }).Count());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCachedQuery
|
||||
{
|
||||
private const string BIKESAVAILABLE = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""bikes"" : {},
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""authcookie"" : """",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
""2352"" : {
|
||||
""description"" : ""Cargo Long"",
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""1"",
|
||||
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
|
||||
""station"" : ""9""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
""bike_soll"" : ""4"",
|
||||
""bike_ist"" : ""1"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""30"" : {
|
||||
""station"" : ""30"",
|
||||
""bike_soll"" : ""5"",
|
||||
""bike_ist"" : ""0"",
|
||||
""station_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Test für Stadtradstation""
|
||||
}
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
private const string STATIONSALLEMPTY = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_StationsFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL),
|
||||
new System.Exception("Bang when getting stations..."))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting stations...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_BikesAvailableFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALLEMPTY))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new System.Exception("Bang when getting bikes..."))));
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting bikes...", result.Exception.Message);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
server.Stub(x => x.AddToCache(Arg<Result<StationsAllResponse>>.Is.Anything));
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable()).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(1, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikesOccupied()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesOccupiedAsync();
|
||||
|
||||
Assert.AreEqual(0, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual(result.Exception.Message, "Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestCachedQueryLoggedIn
|
||||
{
|
||||
private const string BIKESAVAILABLE = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""bikes"" : {},
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""authcookie"" : """",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
""2352"" : {
|
||||
""description"" : ""Cargo Long"",
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""1"",
|
||||
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
|
||||
""station"" : ""9""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
private const string BIKESAVAILABLEEMPTY = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""bikes"" : {},
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""authcookie"" : """",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
}
|
||||
}";
|
||||
|
||||
private const string BIKESOCCUPIED = @"{
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""user_group"" : [ ""TINK"" ],
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""response"" : ""user_bikes_occupied"",
|
||||
""response_state"" : ""OK"",
|
||||
""response_text"" : ""Die Liste der reservierten und gebuchten Fahrräder wurde erfolgreich geladen"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de"",
|
||||
""bikes_occupied"" : {
|
||||
""89004"" : {
|
||||
""start_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""station"" : ""9"",
|
||||
""unit_price"" : ""2.00"",
|
||||
""tariff_description"": {
|
||||
""free_hours"" : ""0.5"",
|
||||
""name"" : ""TINK Tarif"",
|
||||
""max_eur_per_day"" : ""9.00""
|
||||
},
|
||||
""timeCode"" : ""2061"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike"" : ""4"",
|
||||
""total_price"" : ""20.00"",
|
||||
""state"" : ""requested"",
|
||||
""real_hours"" : ""66.05"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""now_time"" : ""2018-01-30 11:36:45"",
|
||||
""request_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""computed_hours"" : ""10.0""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
""bike_soll"" : ""4"",
|
||||
""bike_ist"" : ""1"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""30"" : {
|
||||
""station"" : ""30"",
|
||||
""bike_soll"" : ""5"",
|
||||
""bike_ist"" : ""0"",
|
||||
""station_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Test für Stadtradstation""
|
||||
}
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
private const string STATIONSALLEMPTY = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_StationsFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL),
|
||||
new System.Exception("Bang when getting stations..."))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting stations...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_BikesAvailableFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALLEMPTY))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new System.Exception("Bang when getting bikes..."))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting bikes...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_BikesOccupiedFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALLEMPTY))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLEEMPTY))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
|
||||
new System.Exception("Bang when getting bikes occupied..."))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting bikes occupied...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||
|
||||
server.Stub(x => x.AddToCache(Arg<Result<StationsAllResponse>>.Is.Anything));
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesReservedOccupiedResponse>>.Is.Anything));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes_BikesAvailableFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable()).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new System.Exception("Bang, bikes avail..."))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(2, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang, bikes avail...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes_BikesOccupiedFromCache()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLEEMPTY))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
|
||||
new System.Exception("Bang, error bikes occupied"))));
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(2, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang, error bikes occupied", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesAvailable()).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied()).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesReservedOccupiedResponse>>.Is.Anything));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(2, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikesOccupied()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesOccupied()).Return(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||
|
||||
server.Stub(x => x.AddToCache(Arg<Result<BikesReservedOccupiedResponse>>.Is.Anything));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync();
|
||||
|
||||
Assert.AreEqual(1, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
}
|
||||
}
|
113
TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQuery.cs
Normal file
113
TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQuery.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Query
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestQuery
|
||||
{
|
||||
private const string BIKESAVAILABLE = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""bikes"" : {},
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""authcookie"" : """",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
""2352"" : {
|
||||
""description"" : ""Cargo Long"",
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""1"",
|
||||
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
|
||||
""station"" : ""9""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
""bike_soll"" : ""4"",
|
||||
""bike_ist"" : ""1"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""30"" : {
|
||||
""station"" : ""30"",
|
||||
""bike_soll"" : ""5"",
|
||||
""bike_ist"" : ""0"",
|
||||
""station_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Test für Stadtradstation""
|
||||
}
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
||||
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
|
||||
var result = await new TINK.Model.Connector.Query(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
|
||||
var result = await new TINK.Model.Connector.Query(server).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(1, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikesOccupied()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||
|
||||
var result = await new TINK.Model.Connector.Query(server).GetBikesOccupiedAsync();
|
||||
|
||||
Assert.AreEqual(0, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual(result.Exception.Message, "Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestQueryLoggedIn
|
||||
{
|
||||
private const string BIKESAVAILABLE = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""bikes"" : {},
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://app.tink-konstanz.de"",
|
||||
""authcookie"" : """",
|
||||
""response"" : ""bikes_available"",
|
||||
""bikes"" : {
|
||||
""2352"" : {
|
||||
""description"" : ""Cargo Long"",
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""1"",
|
||||
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
|
||||
""station"" : ""9""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
private const string BIKESOCCUPIED = @"{
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""user_group"" : [ ""TINK"" ],
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""response"" : ""user_bikes_occupied"",
|
||||
""response_state"" : ""OK"",
|
||||
""response_text"" : ""Die Liste der reservierten und gebuchten Fahrräder wurde erfolgreich geladen"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de"",
|
||||
""bikes_occupied"" : {
|
||||
""89004"" : {
|
||||
""start_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""station"" : ""9"",
|
||||
""unit_price"" : ""2.00"",
|
||||
""tariff_description"": {
|
||||
""free_hours"" : ""0.5"",
|
||||
""name"" : ""TINK Tarif"",
|
||||
""max_eur_per_day"" : ""9.00""
|
||||
},
|
||||
""timeCode"" : ""2061"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike"" : ""4"",
|
||||
""total_price"" : ""20.00"",
|
||||
""state"" : ""requested"",
|
||||
""real_hours"" : ""66.05"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""now_time"" : ""2018-01-30 11:36:45"",
|
||||
""request_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""computed_hours"" : ""10.0""
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
""bike_soll"" : ""4"",
|
||||
""bike_ist"" : ""1"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""30"" : {
|
||||
""station"" : ""30"",
|
||||
""bike_soll"" : ""5"",
|
||||
""bike_ist"" : ""0"",
|
||||
""station_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Test für Stadtradstation""
|
||||
}
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||
|
||||
server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
||||
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", ()=> DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(2, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikesOccupied()
|
||||
{
|
||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||
|
||||
server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync();
|
||||
|
||||
Assert.AreEqual(1, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Request;
|
||||
|
||||
namespace UITest.Fixtures.ObjectTests.Connector.Request
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestRequestBuilder
|
||||
{
|
||||
[Test]
|
||||
public void TestDoAuthorize()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=authorization&merchant_id=123&user_id=abc%40cde&user_pw=%2B%3F&hw_id=789",
|
||||
new RequestBuilder("123").DoAuthorization("abc@cde", "+?", "789"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoAuthout()
|
||||
{
|
||||
Assert.Throws<CallNotRequiredException>(() =>
|
||||
new RequestBuilder("123").DoAuthout());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikesAvailable()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=bikes_available&system=all&authcookie=123",
|
||||
new RequestBuilder("123").GetBikesAvailable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikesOccupied()
|
||||
{
|
||||
Assert.Throws< NotSupportedException>(() =>
|
||||
new RequestBuilder("123").GetBikesOccupied());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetStations()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=stations_available&authcookie=123",
|
||||
new RequestBuilder("123").GetStations());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoReserve()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() =>
|
||||
new RequestBuilder("123").DoReserve("42"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoCancelReservation()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() =>
|
||||
new RequestBuilder("123").DoCancelReservation("42"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoSubmitFeedback()
|
||||
{
|
||||
Assert.Throws<NotSupportedException>(() =>
|
||||
new RequestBuilder("123").DoSubmitFeedback("bike3", "Hi", false));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Request;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Request
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestRequestBuilderLoggedIn
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void TestDoAuthorize()
|
||||
{
|
||||
Assert.Throws <CallNotRequiredException>(() =>new RequestBuilderLoggedIn("123", "456").DoAuthorization("abc@cde", "+?", "789"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoAuthout()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=authout&authcookie=456123",
|
||||
new RequestBuilderLoggedIn ("123", "456").DoAuthout());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikesAvailable()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=bikes_available&system=all&authcookie=456123",
|
||||
new RequestBuilderLoggedIn("123", "456").GetBikesAvailable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikesAvailable_Null()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new RequestBuilderLoggedIn("123", null).GetBikesAvailable());
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new RequestBuilderLoggedIn("123", string.Empty).GetBikesAvailable());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikesOccupied()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=user_bikes_occupied&system=all&genkey=1&authcookie=456123",
|
||||
new RequestBuilderLoggedIn("123", "456").GetBikesOccupied());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikesOccupied_Null()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new RequestBuilderLoggedIn("123", null).GetBikesOccupied());
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new RequestBuilderLoggedIn("123", "").GetBikesOccupied());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetStations()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=stations_available&authcookie=456123",
|
||||
new RequestBuilderLoggedIn("123", "456").GetStations());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetStations_Null()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new RequestBuilderLoggedIn("123", string.Empty).GetStations());
|
||||
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
new RequestBuilderLoggedIn("123", null).GetStations());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoReserve()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=booking_request&bike=42&authcookie=456123",
|
||||
new RequestBuilderLoggedIn("123", "456").DoReserve("42"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoCancelReservation()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=booking_cancel&bike=42&authcookie=456123",
|
||||
new RequestBuilderLoggedIn("123", "456").DoCancelReservation("42"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoBook()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=booking_update&bike=42&authcookie=456123&Ilockit_GUID=0000f00d-1212-efde-1523-785fef13d123&state=occupied&lock_state=unlocked&voltage=33.21",
|
||||
new RequestBuilderLoggedIn("123", "456").DoBook("42", new Guid("0000f00d-1212-efde-1523-785fef13d123"),33.21));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoBookNoBatery()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"request=booking_update&bike=42&authcookie=456123&Ilockit_GUID=0000f00d-1212-efde-1523-785fef13d123&state=occupied&lock_state=unlocked",
|
||||
new RequestBuilderLoggedIn("123", "456").DoBook("42", new Guid("0000f00d-1212-efde-1523-785fef13d123"), double.NaN));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Model;
|
||||
using TINK.Repository;
|
||||
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib.Fixtures.Connector
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestBikesAvailableResponse
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserialize_StateAvailable()
|
||||
{
|
||||
// Deserialize object and verify.
|
||||
var l_oContainer = GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 1);
|
||||
Assert.AreEqual(12, l_oContainer.bikes.Count);
|
||||
|
||||
// Check first entry.
|
||||
Assert.AreEqual("Cargo Trike", l_oContainer.bikes["3399"].description);
|
||||
Assert.AreEqual("26", l_oContainer.bikes["3399"].bike);
|
||||
Assert.AreEqual("available", l_oContainer.bikes["3399"].state);
|
||||
Assert.AreEqual("47.6586936667", l_oContainer.bikes["3399"].gps.latitude);
|
||||
Assert.AreEqual("9.16863116667", l_oContainer.bikes["3399"].gps.longitude);
|
||||
Assert.AreEqual("4", l_oContainer.bikes["3399"].station);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Repository;
|
||||
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib.Fixtures.Connector.Response
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestBikesOccupiedResponse
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserialize()
|
||||
{
|
||||
// Deserialize object and verify.
|
||||
var l_oContainer = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1);
|
||||
|
||||
Assert.AreEqual(2, l_oContainer.bikes_occupied.Count);
|
||||
|
||||
// Check first entry.
|
||||
Assert.AreEqual("3630", l_oContainer.bikes_occupied["87781"].timeCode);
|
||||
Assert.AreEqual("occupied", l_oContainer.bikes_occupied["87781"].state);
|
||||
Assert.AreEqual("5", l_oContainer.bikes_occupied["87781"].station);
|
||||
Assert.AreEqual("Cargo Long", l_oContainer.bikes_occupied["87781"].description);
|
||||
Assert.AreEqual("2017-11-28 11:01:51.637747+01", l_oContainer.bikes_occupied["87781"].start_time);
|
||||
Assert.AreEqual("8", l_oContainer.bikes_occupied["87781"].bike);
|
||||
|
||||
// Check first entry.
|
||||
Assert.AreEqual("2931", l_oContainer.bikes_occupied["87782"].timeCode);
|
||||
Assert.AreEqual("occupied", l_oContainer.bikes_occupied["87782"].state);
|
||||
Assert.AreEqual("4", l_oContainer.bikes_occupied["87782"].station);
|
||||
Assert.AreEqual("Cargo Long", l_oContainer.bikes_occupied["87782"].description);
|
||||
Assert.AreEqual("2017-11-28 13:06:55.147368+01", l_oContainer.bikes_occupied["87782"].start_time);
|
||||
Assert.AreEqual("7", l_oContainer.bikes_occupied["87782"].bike);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserialize_StateReserved()
|
||||
{
|
||||
// Deserialize object and verify.
|
||||
var l_oContainer = CopriCallsMemory.GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2);
|
||||
Assert.AreEqual(3, l_oContainer.bikes_occupied.Count);
|
||||
|
||||
// Check first entry.
|
||||
Assert.AreEqual("Cargo Long", l_oContainer.bikes_occupied["2360"].description);
|
||||
Assert.AreEqual("5", l_oContainer.bikes_occupied["2360"].bike);
|
||||
Assert.AreEqual("reserved", l_oContainer.bikes_occupied["2360"].state);
|
||||
Assert.AreEqual("4", l_oContainer.bikes_occupied["2360"].station);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib.Fixtures.Connector.Response
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestBookingResponse
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserialize()
|
||||
{
|
||||
// Deserialize object and verify.
|
||||
var l_oContainer = CopriCallsMemory.DoReserve("8", "b76b97e43a2d76b8499f32e6dd597af8", SampleSets.Set2, 1);
|
||||
|
||||
Assert.AreEqual(2, l_oContainer.bikes_occupied.Count);
|
||||
Assert.AreEqual("3630", l_oContainer.timeCode);
|
||||
Assert.AreEqual("OK: requested bike 8", l_oContainer.response_state);
|
||||
|
||||
// Check first entry which is bike #8
|
||||
Assert.AreEqual("3630", l_oContainer.bikes_occupied["87781"].timeCode);
|
||||
Assert.AreEqual("occupied", l_oContainer.bikes_occupied["87781"].state);
|
||||
Assert.AreEqual("5", l_oContainer.bikes_occupied["87781"].station);
|
||||
Assert.AreEqual("Cargo Long", l_oContainer.bikes_occupied["87781"].description);
|
||||
Assert.AreEqual("2017-11-28 11:01:51.637747+01", l_oContainer.bikes_occupied["87781"].start_time);
|
||||
Assert.AreEqual("8", l_oContainer.bikes_occupied["87781"].bike);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsBookingResponseSucceeded()
|
||||
{
|
||||
// Create response to check
|
||||
var l_oResponse = DoReserve(
|
||||
"8",
|
||||
"4da3044c8657a04ba60e2eaa753bc51a",
|
||||
SampleSets.Set2,
|
||||
1);
|
||||
|
||||
Assert.AreEqual(
|
||||
"4da3044c8657a04ba60e2eaa753bc51aoiF2kahH",
|
||||
l_oResponse.authcookie);
|
||||
|
||||
Assert.AreEqual(
|
||||
"OK: requested bike 8",
|
||||
l_oResponse.response_state);
|
||||
|
||||
Assert.NotNull(
|
||||
l_oResponse.GetIsReserveResponseOk("8"),
|
||||
"Booking did succeed, response must not be null.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
|
||||
|
||||
namespace TINK.Repository.Response
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestResponseBase
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserialize()
|
||||
{
|
||||
// Deserialize object and verify.
|
||||
var l_oContainer = CopriCallsMemory.DoAuthorize("javaminister@gmail.com", "javaminister", "HwId1000000000000");
|
||||
|
||||
// Check first entry.
|
||||
Assert.AreEqual("authorization", l_oContainer.response);
|
||||
Assert.AreEqual("4da3044c8657a04ba60e2eaa753bc51a", l_oContainer.authcookie);
|
||||
Assert.AreEqual("OK", l_oContainer.response_state);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestToString()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<ResponseBase>(@"
|
||||
{
|
||||
""response_state"": ""OhMyState"",
|
||||
""response"": ""HabGsagt"",
|
||||
""response_text"": ""die Antwort"",
|
||||
""authcookie"": ""lecker1"",
|
||||
""copri_version"":""123""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(
|
||||
"Response state is \"OhMyState\", " +
|
||||
$"auth cookie is \"lecker1\" and response is \"die Antwort\", " +
|
||||
$"code \"HabGsagt\""+
|
||||
$"response text \"die Antwort\".",
|
||||
l_oResponse.ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Response
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestResponseHelper
|
||||
{
|
||||
[Test]
|
||||
public void TestGetIsResponseOk_BikesOccupied_Ok()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(@"{ ""response_state"" : ""OK"" }");
|
||||
Assert.NotNull(l_oResponse.GetIsResponseOk(ResponseHelper.BIKES_OCCUPIED_ACTIONTEXT));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsResponseOk_BikesOccupied_AuthcookieNotDefined()
|
||||
{
|
||||
var l_oResponseBase = JsonConvert.DeserializeObject<ResponseBase>($"{{ \"response_state\" : \"Failure 1003: authcookie not defined\" }}");
|
||||
Assert.Throws<AuthcookieNotDefinedException>(() => l_oResponseBase.GetIsResponseOk("Get not succeed"));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestGetIsResponseOk_NoBikes()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<ReservationBookingResponse>(
|
||||
@"{ ""response_state"" : ""OK"", " +
|
||||
@"""authcookie"" : ""KeksoiF2kahH"" }");
|
||||
|
||||
Assert.That(() => l_oResponse.GetIsReserveResponseOk("8"), Throws.Exception.TypeOf<System.Exception>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsResposeOk_Booking_Declined()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<ReservationBookingResponse>(@"{ ""response_state"" : ""OK: booking_request declined. max count of 8 occupied bikes has been reached"", ""authcookie"" : ""KeksoiF2kahH"" }");
|
||||
Assert.AreEqual(
|
||||
8,
|
||||
Assert.Throws<BookingDeclinedException>(() => l_oResponse.GetIsReserveResponseOk("8")).MaxBikesCount);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsResposeOk_Logout_AutcookieUnknown()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<AuthorizationoutResponse>($"{{ \"response_state\" : \"Failure 1004: authcookie not defined\"}}");
|
||||
|
||||
Assert.Throws<AuthcookieNotDefinedException>(() => l_oResponse.GetIsResponseOk());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsReturnBikeResponseOk_Error()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<ReservationCancelReturnResponse>(
|
||||
@"{ ""response_state"" : ""Failure 1234"", " +
|
||||
@"""authcookie"" : ""KeksoiF2kahH"" }");
|
||||
|
||||
Assert.That(
|
||||
() => l_oResponse.GetIsReturnBikeResponseOk("8"),
|
||||
Throws.Exception.TypeOf<InvalidResponseException<ResponseBase>>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsReturnBikeResponseOk_ErrorNotAtStation()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<ReservationCancelReturnResponse>(
|
||||
@"{ ""response_state"" : ""Failure 2178: bike 1545 out of GEO fencing. 15986 meter distance to next station 66. OK: bike 1545 locked confirmed"", " +
|
||||
@"""authcookie"" : ""KeksoiF2kahH"" }");
|
||||
|
||||
Assert.That(() => l_oResponse.GetIsReturnBikeResponseOk("8"), Throws.Exception.TypeOf<NotAtStationException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsReturnBikeResponseOk_ErrorNoGPSData()
|
||||
{
|
||||
var l_oResponse = JsonConvert.DeserializeObject<ReservationCancelReturnResponse>(
|
||||
@"{ ""response_state"" : ""Failure 2245: No GPS data, state change forbidden."", " +
|
||||
@"""authcookie"" : ""KeksoiF2kahH"" }");
|
||||
|
||||
Assert.That(() => l_oResponse.GetIsReturnBikeResponseOk("8"), Throws.Exception.TypeOf<NoGPSDataException>());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using TINK.Model;
|
||||
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib.Fixtures.Connector
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStationsAllResponse
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserialize()
|
||||
{
|
||||
// Deserialize object and verify.
|
||||
var l_oContainer = GetStationsAll(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 1);
|
||||
Assert.AreEqual(9, l_oContainer.stations.Count);
|
||||
|
||||
// Check first entry (type TINK).
|
||||
Assert.AreEqual("4", l_oContainer.stations["5786"].station);
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oContainer.stations["5786"].station_group));
|
||||
Assert.IsNull(l_oContainer.stations["5786"].description);
|
||||
Assert.AreEqual("47.6586936667", l_oContainer.stations["5786"].gps.latitude);
|
||||
Assert.AreEqual("9.16863116667", l_oContainer.stations["5786"].gps.longitude);
|
||||
|
||||
// Check Konrad entry.
|
||||
Assert.AreEqual("14", l_oContainer.stations["14"].station);
|
||||
Assert.AreEqual("Konrad", string.Join(",", l_oContainer.stations["14"].station_group));
|
||||
Assert.AreEqual(string.Empty, l_oContainer.stations["14"].description);
|
||||
Assert.AreEqual("47.66698054007847", l_oContainer.stations["14"].gps.latitude);
|
||||
Assert.AreEqual("9.169303178787231", l_oContainer.stations["14"].gps.longitude);
|
||||
|
||||
// Check TINK/ Konrad entry.
|
||||
Assert.AreEqual("31", l_oContainer.stations["31"].station);
|
||||
Assert.AreEqual("TINK,Konrad", string.Join(",", l_oContainer.stations["31"].station_group));
|
||||
Assert.AreEqual("Südstadt Station", l_oContainer.stations["31"].description);
|
||||
Assert.AreEqual("47.69489", l_oContainer.stations["31"].gps.latitude);
|
||||
Assert.AreEqual("9.19", l_oContainer.stations["31"].gps.longitude);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCommandLoggedIn
|
||||
{
|
||||
/// <summary> Verifies, that logout leads to expected call on copri server. </summary>
|
||||
[Test]
|
||||
public void TestDoLogout()
|
||||
{
|
||||
var l_oServer = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
l_oServer.Stub(x => x.DoAuthoutAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<AuthorizationoutResponse>("{ \"response_state\" : \"OK\", \"authcookie\" : \"1\"}")));
|
||||
|
||||
var l_oCmd = new CommandLoggedIn(l_oServer, "MeinKeks", "EMehl", () => DateTime.Now);
|
||||
|
||||
LoginStateChangedEventArgs l_oEventArgs = null;
|
||||
l_oCmd.LoginStateChanged += (sender, eventargs) => l_oEventArgs = eventargs;
|
||||
|
||||
l_oCmd.DoLogout().Wait();
|
||||
|
||||
l_oServer.AssertWasCalled(x => x.DoAuthoutAsync());
|
||||
Assert.IsNotNull(l_oEventArgs);
|
||||
}
|
||||
|
||||
/// <summary> Verifies, that logout leads to expected call on copri server. </summary>
|
||||
[Test]
|
||||
public void TestDoLogout_AuthcookieNotDefined()
|
||||
{
|
||||
var l_oServer = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
l_oServer.Stub(x => x.DoAuthoutAsync()).Throw(new AuthcookieNotDefinedException("Testing action", JsonConvert.DeserializeObject<ResponseBase>(@"{ ""response_state"" : ""Some inner error description""}")));
|
||||
|
||||
var l_oCmd = new CommandLoggedIn(l_oServer, "MeinKeks", "EMehl", () => DateTime.Now);
|
||||
|
||||
LoginStateChangedEventArgs l_oEventArgs = null;
|
||||
l_oCmd.LoginStateChanged += (sender, eventargs) => l_oEventArgs = eventargs;
|
||||
|
||||
l_oCmd.DoLogout().Wait();
|
||||
|
||||
l_oServer.AssertWasCalled(x => x.DoAuthoutAsync());
|
||||
Assert.IsNotNull(l_oEventArgs);
|
||||
}
|
||||
|
||||
/// <summary> Verifies, that logout leads to expected call on copri server. </summary>
|
||||
[Test]
|
||||
public void TestDoLogout_Exception()
|
||||
{
|
||||
var l_oServer = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
l_oServer.Stub(x => x.DoAuthoutAsync()).Throw(new System.Exception("Sometheing went wrong."));
|
||||
|
||||
var l_oCmd = new CommandLoggedIn(l_oServer, "MeinKeks", "EMehl", () => DateTime.Now);
|
||||
|
||||
LoginStateChangedEventArgs l_oEventArgs = null;
|
||||
l_oCmd.LoginStateChanged += (sender, eventargs) => l_oEventArgs = eventargs;
|
||||
|
||||
Assert.Throws<AggregateException>(() => l_oCmd.DoLogout().Wait());
|
||||
|
||||
l_oServer.AssertWasCalled(x => x.DoAuthoutAsync());
|
||||
Assert.IsNull(l_oEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
84
TestTINKLib/Fixtures/ObjectTests/Connector/TestConnector.cs
Normal file
84
TestTINKLib/Fixtures/ObjectTests/Connector/TestConnector.cs
Normal file
|
@ -0,0 +1,84 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestConnector
|
||||
{
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCommandFactory()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICachedCopriServer>();
|
||||
|
||||
// Construct not logged in version of connector.
|
||||
var l_oCommand = new TINK.Model.Connector.Connector(
|
||||
new System.Uri("http://1.2.3.4"),
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default automated test envirnoment",
|
||||
"", // Not logged in
|
||||
"",
|
||||
server: l_oCopri).Command;
|
||||
|
||||
Assert.AreEqual(typeof(Command), l_oCommand.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCommandFactory_LoggedIn()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICachedCopriServer>();
|
||||
|
||||
var l_oCommand = new TINK.Model.Connector.Connector(
|
||||
new System.Uri("http://1.2.3.4"),
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default automated test envirnoment",
|
||||
"123", // Logged in
|
||||
"a@b",
|
||||
server: l_oCopri).Command;
|
||||
|
||||
Assert.AreEqual(typeof(CommandLoggedIn), l_oCommand.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestQueryFactory_CachedServer()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICachedCopriServer>();
|
||||
|
||||
var l_oQuery = new TINK.Model.Connector.Connector(
|
||||
new System.Uri("http://1.2.3.4"),
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default automated test envirnoment",
|
||||
"",
|
||||
"",
|
||||
server: l_oCopri).Query;
|
||||
|
||||
Assert.AreEqual(typeof(CachedQuery), l_oQuery.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestQueryFactory_LoggedIn()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICachedCopriServer>();
|
||||
|
||||
var l_oQuery = new TINK.Model.Connector.Connector(
|
||||
new System.Uri("http://1.2.3.4"),
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default automated test envirnoment",
|
||||
"123",
|
||||
"a@b",
|
||||
server: l_oCopri).Query;
|
||||
|
||||
Assert.AreEqual(typeof(CachedQueryLoggedIn), l_oQuery.GetType());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestConnectorCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCommandFactory()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
// Construct not logged in version of connector.
|
||||
var l_oCommand = new ConnectorCache(
|
||||
"", // Not logged in
|
||||
"",
|
||||
l_oCopri).Command;
|
||||
|
||||
Assert.AreEqual(typeof(Command), l_oCommand.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCommandFactory_LoggedIn()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
var l_oCommand = new ConnectorCache(
|
||||
"123", // Logged in
|
||||
"a@b",
|
||||
l_oCopri).Command;
|
||||
|
||||
Assert.AreEqual(typeof(CommandLoggedIn), l_oCommand.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestQueryFactory_CachedServer()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
var l_oQuery = new ConnectorCache(
|
||||
"",
|
||||
"",
|
||||
l_oCopri).Query;
|
||||
|
||||
Assert.AreEqual(typeof(TINK.Model.Connector.Query), l_oQuery.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that factory method returns correcty type depending on session cookie.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestQueryFactory_LoggedIn()
|
||||
{
|
||||
var l_oCopri = MockRepository.GenerateStub<ICopriServer>();
|
||||
|
||||
var l_oQuery = new ConnectorCache(
|
||||
"123",
|
||||
"a@b",
|
||||
l_oCopri).Query;
|
||||
|
||||
Assert.AreEqual(typeof(QueryLoggedIn), l_oQuery.GetType());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,688 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using TINK.Model;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Repository.Request;
|
||||
|
||||
using static TINK.Repository.CopriCallsHttps;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UITest.Fixtures.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCopriCallsHttps
|
||||
{
|
||||
public const string CATEGORY_REQUIRESCOPRI = "RequiresCOPRI";
|
||||
|
||||
public const string CATEGORY_USESLIVESERVER = "RequiresCOPRI.Live";
|
||||
|
||||
public const string CATEGORY_USESDEVELSERVER = "RequiresCOPRI.Devel";
|
||||
|
||||
public const string TESTAGENT = "TestShareeLib";
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
Thread.Sleep(2000); // Sleep, otherwise copri will block requested calls.
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsConnected()
|
||||
{
|
||||
Assert.IsTrue(new CopriCallsHttps(new Uri("http://127.0.0.0/api"), "TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default", "123").IsConnected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestLogin(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
Func<string, string> command = (password) => new RequestBuilder(TinkApp.MerchantId).DoAuthorization(
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
password,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
|
||||
var l_oSessionCookieJM_Dev1 = DoAuthorizationAsync(
|
||||
url,
|
||||
command(TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd),
|
||||
() => command("*******"),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestLogin)}").Result;
|
||||
|
||||
Assert.AreEqual(
|
||||
string.Format("{0}{1}", "6103_4da3044c8657a04ba60e2eaa753bc51a_", "oiF2kahH"),
|
||||
l_oSessionCookieJM_Dev1.authcookie,
|
||||
"Session cookie must never change if user and hardware id does not change.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestLogin_UserUnknown(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
Func<string, string> command = (password) => new RequestBuilder(TinkApp.MerchantId).DoAuthorization(
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerGibtsNet.Mail,
|
||||
password,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerGibtsNet.DeviceId);
|
||||
|
||||
var l_oSessionCookieJM_Dev1 = DoAuthorizationAsync(
|
||||
url,
|
||||
command(TestTINKLib.LoginSessionCopriInfo.JavaministerGibtsNet.Pwd),
|
||||
() => command("***********"),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestLogin_UserUnknown)}").Result;
|
||||
|
||||
Assert.That(
|
||||
l_oSessionCookieJM_Dev1,
|
||||
Is.Not.Null);
|
||||
|
||||
// From COPRI 4.1 cookie is empty, was null before
|
||||
Assert.IsEmpty(l_oSessionCookieJM_Dev1.authcookie);
|
||||
|
||||
Assert.AreEqual(
|
||||
"authorization",
|
||||
l_oSessionCookieJM_Dev1.response);
|
||||
|
||||
Assert.AreEqual(
|
||||
"Failure: cannot generate authcookie",
|
||||
l_oSessionCookieJM_Dev1.response_state);
|
||||
}
|
||||
|
||||
/// <summary> Log out functionality is only for test purposes. </summary>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestLogout(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
// Prerequisite: Login must be performed before logging out.
|
||||
var l_oSessionCookie = CopriCallsHttpsReference.DoAuthorizeCall(
|
||||
url,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
|
||||
Assert.IsFalse(
|
||||
string.IsNullOrEmpty(l_oSessionCookie?.authcookie),
|
||||
"Prerequisites not matched: User must be logged on before beeing able to log out.");
|
||||
|
||||
// Verify logout
|
||||
try
|
||||
{
|
||||
Assert.NotNull(DoAuthoutAsync(
|
||||
url,
|
||||
new RequestBuilderLoggedIn(
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).DoAuthout(),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestLogout)}"
|
||||
).Result.GetIsResponseOk());
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Log in again to ensure that tests do not change state of database (assumtion: user is always logged in).
|
||||
CopriCallsHttpsReference.DoAuthorizeCall(
|
||||
url,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log out functionality is only for test purposes.
|
||||
/// </summary>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestLogout_NotLoggedIn(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
// Prerequisite:
|
||||
// Ensure that user is really logged out and get valid session cookie before verifying logout behavior.
|
||||
var l_oLoginResponse = CopriCallsHttpsReference.DoAuthorizeCall(
|
||||
url,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
|
||||
Assert.IsFalse(
|
||||
string.IsNullOrEmpty(l_oLoginResponse?.authcookie),
|
||||
"Prerequisites not matched: User must be logged out before beeing able to log out.");
|
||||
|
||||
CopriCallsHttpsReference.DoAuthoutCall(url, TinkApp.MerchantId, l_oLoginResponse.authcookie);
|
||||
|
||||
try
|
||||
{
|
||||
// Verify logout
|
||||
Assert.Throws<AuthcookieNotDefinedException>(
|
||||
() => DoAuthoutAsync(
|
||||
url,
|
||||
new RequestBuilderLoggedIn(TinkApp.MerchantId, l_oLoginResponse.authcookie).DoAuthout(),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestLogout_NotLoggedIn)}").Result.GetIsResponseOk());
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Log in again. Otherwise subsequent tests might fail.
|
||||
l_oLoginResponse = CopriCallsHttpsReference.DoAuthorizeCall(
|
||||
new CopriServerUriList().ActiveUri.AbsoluteUri,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log out is performed by app programmatically if authcookie is no more valid.
|
||||
/// Must work even if authcookie is no more valid, otherwise login would not be avalable.
|
||||
/// </summary>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestLogout_AuthcookieUnknown(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
// Prerequisite: Login must be formormed before logging out.
|
||||
var l_oSessionCookie = CopriCallsHttpsReference.DoAuthorizeCall(
|
||||
url,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
|
||||
Assert.IsFalse(
|
||||
string.IsNullOrEmpty(l_oSessionCookie?.authcookie),
|
||||
"Prerequisites not matched: User must be logged on before beeing able to log out.");
|
||||
|
||||
// Verify logout that expected excepton is thrown.
|
||||
try
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"Failure 1001: authcookie not defined", // Up to 2020-12-05 COPRI returned: "Failure 1004: authcookie not defined"
|
||||
DoAuthoutAsync(
|
||||
url,
|
||||
new RequestBuilderLoggedIn(
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerKeksGibtsNet.AuthCookie).DoAuthout(),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestLogout_AuthcookieUnknown)}"
|
||||
).Result.response_state);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Log in again to ensure that tests do not change state of database (assumtion: user is always logged in).
|
||||
CopriCallsHttpsReference.DoAuthorizeCall(
|
||||
url,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.DeviceId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestGetBikesAvailalbleCall_LoggedId(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
// Check prerequisites: At least one bike must be available.
|
||||
var bikesReference = CopriCallsHttpsReference.GetBikesAvailableCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes;
|
||||
Assert.NotNull(bikesReference);
|
||||
var bikeReference = bikesReference.FirstOrDefault().Value;
|
||||
Assert.That(
|
||||
bikeReference,
|
||||
Is.Not.Null,
|
||||
$"Prerequisites are not matched: No bikes available from server {url} returned but at least one bike for verification required.");
|
||||
|
||||
// Verify list of bikes returned from first device
|
||||
var request = new RequestBuilderLoggedIn(
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).GetBikesAvailable();
|
||||
|
||||
var bikes = GetBikesAvailableAsync(
|
||||
url,
|
||||
request).Result.bikes;
|
||||
|
||||
Assert.That(
|
||||
bikes,
|
||||
Is.Not.Null,
|
||||
"Response is null.");
|
||||
|
||||
var bike = bikes.FirstOrDefault().Value;
|
||||
Assert.That(
|
||||
bike,
|
||||
Is.Not.Null,
|
||||
"Response on GetBikesAvailableCall must contain at leas one bike.");
|
||||
|
||||
// Check if entries are valid.
|
||||
Assert.Greater(
|
||||
bike.description.Length,
|
||||
0,
|
||||
"Bike despcription must never be empty.");
|
||||
|
||||
Assert.That(
|
||||
bike.bike,
|
||||
Is.Not.Null,
|
||||
"Bike index must never be null");
|
||||
|
||||
Assert.AreEqual(
|
||||
"available",
|
||||
bike.state,
|
||||
"Bike state must be available");
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestGetBikesAvailalbleCall_NotLoggedId(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
// Check prerequisites: At least one bike must be available.
|
||||
var bikeReference = CopriCallsHttpsReference.GetBikesAvailableCall(url, TinkApp.MerchantId)?.bikes?.FirstOrDefault().Value;
|
||||
Assert.That(
|
||||
bikeReference,
|
||||
Is.Not.Null,
|
||||
$"Prerequisites are not matched: No bikes available from server {url} returned but at least one bike for verification required.");
|
||||
|
||||
// Verify list of bikes returned from first device
|
||||
var request = new RequestBuilder(TinkApp.MerchantId).GetBikesAvailable();
|
||||
|
||||
var bikes = GetBikesAvailableAsync(
|
||||
url,
|
||||
request,
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestGetBikesAvailalbleCall_NotLoggedId)}").Result.bikes;
|
||||
|
||||
Assert.That(
|
||||
bikes,
|
||||
Is.Not.Null,
|
||||
"Response is null.");
|
||||
|
||||
var bike = bikes.FirstOrDefault().Value;
|
||||
Assert.That(
|
||||
bike,
|
||||
Is.Not.Null,
|
||||
"Response on GetBikesAvailableCall must contain at leas one bike.");
|
||||
|
||||
// Check if entries are valid.
|
||||
Assert.Greater(
|
||||
bike.description.Length,
|
||||
0,
|
||||
"Bike despcription must never be empty.");
|
||||
|
||||
Assert.That(
|
||||
bike.bike,
|
||||
Is.Not.Null,
|
||||
"Bike index must never be null");
|
||||
|
||||
Assert.AreEqual(
|
||||
"available",
|
||||
bike.state,
|
||||
"Bike state must be available");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attention: Behaves different if called with a period smaller 15minutes because bike will alreay be reserved.
|
||||
/// </summary>
|
||||
[Test, Explicit, Ignore("Avoid testrunner running explicit tests.")]
|
||||
public void TestDoReserveCall(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
Assert.Less(
|
||||
CopriCallsHttpsReference.GetBikesOccupiedCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes_occupied.Count,
|
||||
3,
|
||||
"Too many bikes requested/ booked.");
|
||||
|
||||
var l_oBikesAvailable = CopriCallsHttpsReference.GetBikesAvailableCall(CopriServerUriList.DevelopUri.AbsoluteUri, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes;
|
||||
|
||||
Assert.Greater(
|
||||
l_oBikesAvailable.Count,
|
||||
0,
|
||||
"There must be at least one bike available.");
|
||||
|
||||
// Id of bike to book
|
||||
string l_oBikeId = l_oBikesAvailable.ToArray()[0].Value.bike;
|
||||
|
||||
// Check prerequisites.
|
||||
// State of bike for which to cancel booking must be available.
|
||||
Assert.NotNull(
|
||||
CopriCallsHttpsReference.GetBikesAvailableCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes?.FirstOrDefault(x => x.Value.bike == l_oBikeId).Value,
|
||||
"Prerequities check failed: Bike with given id must be available;");
|
||||
|
||||
var l_oBookingResponse = DoReserveAsync(
|
||||
CopriServerUriList.DevelopUri.AbsoluteUri,
|
||||
new RequestBuilderLoggedIn(
|
||||
TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).DoReserve(l_oBikeId)).Result;
|
||||
|
||||
try
|
||||
{
|
||||
// If response_state is "Failure 2001: booking bike 20 . maybe not available" probale test was run already and bike got reserved.
|
||||
Assert.AreEqual(string.Format("OK: requested bike {0}", l_oBikeId), l_oBookingResponse.response_state);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Clean up to ensure that running tests does not modify data base.
|
||||
CopriCallsHttpsReference.DoCancelReservationCall(url, TinkApp.MerchantId, l_oBikeId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attention: Behaves different if called with a period smaller 15minutes because bike will alreay be reserved.
|
||||
/// </summary>
|
||||
[Test, Explicit, Ignore("Avoid testrunner running explicit tests.")]
|
||||
public void TestDoCancelReservationCall(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
|
||||
{
|
||||
Assert.Less(
|
||||
CopriCallsHttpsReference.GetBikesOccupiedCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes_occupied.Count,
|
||||
3,
|
||||
"Too many bikes requested/ booked.");
|
||||
|
||||
var l_oBikesAvailable = CopriCallsHttpsReference.GetBikesAvailableCall(CopriServerUriList.DevelopUri.AbsoluteUri, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes;
|
||||
|
||||
Assert.Greater(
|
||||
l_oBikesAvailable.Count,
|
||||
0,
|
||||
"There must be at least one bike available.");
|
||||
|
||||
// Id of bike to book
|
||||
string l_oBikeId = l_oBikesAvailable.ToArray()[0].Value.bike;
|
||||
|
||||
// Check prerequisites.
|
||||
var l_oBikeToCancel = CopriCallsHttpsReference.GetBikesAvailableCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes?.FirstOrDefault(x => x.Value.bike == l_oBikeId).Value;
|
||||
if (l_oBikeToCancel != null)
|
||||
{
|
||||
// Bike is avilable. Do request before unning test.
|
||||
CopriCallsHttpsReference.DoReserveCall(url, TinkApp.MerchantId, l_oBikeId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie);
|
||||
}
|
||||
|
||||
// State of bike for which to cancel booking must be reserved.
|
||||
var l_oReservedBike = CopriCallsHttpsReference.GetBikesOccupiedCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).bikes_occupied.FirstOrDefault(x => x.Value.bike == l_oBikeId).Value;
|
||||
Assert.NotNull(l_oReservedBike, string.Format("Setup test failed. Bike with id {0} must be booked before verifying cancel of booking.", l_oReservedBike));
|
||||
Assert.AreEqual("requested", l_oReservedBike.state, string.Format("Setup test failed. Bike with id {0} must be booked before verifying cancel of booking.", l_oReservedBike));
|
||||
|
||||
// Test cancel booking
|
||||
var l_oBookingResponse = DoCancelReservationAsync(
|
||||
CopriServerUriList.DevelopUri.AbsoluteUri,
|
||||
new RequestBuilderLoggedIn(
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).DoReserve(l_oBikeId)).Result;
|
||||
|
||||
try
|
||||
{
|
||||
Assert.AreEqual(string.Format("OK: canceled bike {0}", l_oBikeId), l_oBookingResponse.response_state);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Clean up to ensure that running tests does not modify data base.
|
||||
CopriCallsHttpsReference.DoCancelReservationCall(url, TinkApp.MerchantId, l_oBikeId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Tests the member.</summary>
|
||||
/// <remarks>Timecode is no more verified since COPRI 4.1.</remarks>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestGetBikesOccupiedCall_SomeRequestedBooked(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)]
|
||||
string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
BikesReservedOccupiedResponse l_oBookingResponse;
|
||||
var bikesOccupied = CopriCallsHttpsReference.GetBikesOccupiedCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes_occupied;
|
||||
if (bikesOccupied == null || bikesOccupied.Count < 1)
|
||||
{
|
||||
// There must be at least one bike booked.
|
||||
var bikesAvailable = CopriCallsHttpsReference.GetBikesAvailableCall(
|
||||
url,
|
||||
TinkApp.MerchantId,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes;
|
||||
|
||||
Assert.Greater(
|
||||
bikesAvailable.Count,
|
||||
0,
|
||||
"Prerequisites are not matched: There must be at least one bike available.");
|
||||
|
||||
// Id of bike to book
|
||||
var bike = bikesAvailable.ToArray()[0].Value;
|
||||
|
||||
l_oBookingResponse = CopriCallsHttpsReference.DoReserveCall(
|
||||
bike.uri_operator + "/APIjsonserver",
|
||||
TinkApp.MerchantId,
|
||||
bike.bike,
|
||||
TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie);
|
||||
|
||||
Assert.That(l_oBookingResponse.GetIsResponseOk("Testing cotext"),
|
||||
!Is.Null,
|
||||
$"Booking must succeed. {l_oBookingResponse.response_text}");
|
||||
}
|
||||
|
||||
// Verify GetBikesOccupied call.
|
||||
var l_oBike = CopriCallsHttpsReference.GetBikesOccupiedCall(url, TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie)?.bikes_occupied?.FirstOrDefault().Value;
|
||||
Assert.NotNull(l_oBike, "Response on GetBikesOccupiedCall of must contain at least one bike.");
|
||||
|
||||
l_oBookingResponse = GetBikesOccupiedAsync(
|
||||
url,
|
||||
new RequestBuilderLoggedIn(TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).GetBikesOccupied(),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestGetBikesOccupiedCall_SomeRequestedBooked)}").Result;
|
||||
|
||||
// Check first entry.
|
||||
Assert.AreEqual(
|
||||
string.Format("{0}{1}", TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie, TinkApp.MerchantId),
|
||||
l_oBookingResponse.authcookie);
|
||||
|
||||
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
|
||||
Assert.That(l_oBike.bike, Is.Not.Null, "Bike index must not be null.");
|
||||
Assert.That(
|
||||
l_oBike.station,
|
||||
Is.Not.Null,
|
||||
"Station index must never be null");
|
||||
Assert.Greater(l_oBike.state.Length, 0, "State info must never be null or empty.");
|
||||
// Todo: Requested bikes do not have a gps position. What is about booked bikes?
|
||||
// Assert.Greater(l_oBike.gps.Length, 0, "Gps position must never be empty.");
|
||||
Assert.Greater(l_oBike.start_time.Length, 0, "Time when request/ booking was performed must never be null or empty.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the member.
|
||||
/// Call GetBikesOccupiedCall is first call of app which fails (throws AuthcookieNotDefinedException) if auth cookie is invalid.
|
||||
/// If app detects AuthcookieNotDefinedException exception user is logged out.
|
||||
/// </summary>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestGetBikesOccupiedCall_KeksGibtsNet(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
var request = new RequestBuilderLoggedIn(TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerKeksGibtsNet.AuthCookie).GetBikesOccupied();
|
||||
|
||||
var l_oBookingResponse = GetBikesOccupiedAsync(
|
||||
url,
|
||||
request,
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestGetBikesOccupiedCall_KeksGibtsNet)}").Result;
|
||||
|
||||
Assert.AreEqual(
|
||||
"Failure 1001: authcookie on primary not defined",
|
||||
l_oBookingResponse.response_state); // Up to 2020-12-05 COPRI returned: "Failure 1003: authcookie not defined"
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the member.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
[Category(CATEGORY_REQUIRESCOPRI)]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#endif
|
||||
public void TestGetStationsAllCall_NotLoggedIn(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
// Check prerequisites: At least one bike must be available.
|
||||
var l_oStationsReference = CopriCallsHttpsReference.GetStationsAllCall(url, TinkApp.MerchantId)?.stations;
|
||||
Assert.IsTrue(
|
||||
l_oStationsReference != null && l_oStationsReference.Count > 0,
|
||||
"Prerequisites are not matched: There are no stations.");
|
||||
|
||||
// Verify implementation
|
||||
var l_oStationsAll = GetStationsAsync(url, new RequestBuilder(TinkApp.MerchantId).GetStations()).Result;
|
||||
Assert.NotNull(l_oStationsAll?.stations);
|
||||
Assert.Greater(l_oStationsAll.stations.Count, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests the member.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
#if !NOLIVESERVER
|
||||
[Category(CATEGORY_USESLIVESERVER)]
|
||||
#elif !NODEVELSERVER
|
||||
[Category(CATEGORY_USESDEVELSERVER)]
|
||||
#endif
|
||||
public void TestGetStationsAllCall_LoggedIn(
|
||||
#if NOLIVESERVER
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL)] string url)
|
||||
#elif NODEVELSERVER
|
||||
[Values(CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#else
|
||||
[Values(CopriServerUriList.SHAREE_DEVEL, CopriServerUriList.SHAREE_LIVE)] string url)
|
||||
#endif
|
||||
{
|
||||
var stationsAll = GetStationsAsync(
|
||||
url,
|
||||
new RequestBuilderLoggedIn(TinkApp.MerchantId, TestTINKLib.LoginSessionCopriInfo.JavaministerHardwareNr1.AuthCookie).GetStations(),
|
||||
$"{Assembly.GetAssembly(GetType()).GetName().Name}-{GetType().Name}-{nameof(TestGetStationsAllCall_LoggedIn)}").Result;
|
||||
|
||||
Assert.NotNull(stationsAll?.stations);
|
||||
Assert.That(
|
||||
stationsAll.stations.Count,
|
||||
Is.GreaterThan(0),
|
||||
$"There must be at least one station.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib.Fixtures.Connector.Request
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestCopriCallsMemory
|
||||
{
|
||||
[Test]
|
||||
public void TestConsistency()
|
||||
{
|
||||
foreach (SampleSets l_oSampleSet in Enum.GetValues(typeof(SampleSets)))
|
||||
{
|
||||
var l_oCopri = new CopriCallsMemory(l_oSampleSet, 1, "4da3044c8657a04ba60e2eaa753bc51a");
|
||||
|
||||
for (var l_iStageIndex = 1; l_iStageIndex <= l_oCopri.StagesCount; l_iStageIndex++)
|
||||
{
|
||||
Assert.That(l_oCopri.GetBikesAvailableAsync().Result?.bikes, Is.Not.Null, $"There must be at least one bike for sample set {l_oSampleSet}, stage {l_iStageIndex}.");
|
||||
VerifyBikeIdIsUnique(l_oCopri);
|
||||
|
||||
Assert.IsNull(
|
||||
l_oCopri.GetBikesAvailableAsync().Result.bikes.Values.FirstOrDefault(x => x.state != "available"),
|
||||
"Bikes available must return bikes which are all of state available.");
|
||||
|
||||
Assert.IsNull(
|
||||
l_oCopri.GetBikesOccupiedAsync().Result.bikes_occupied.Values.FirstOrDefault(x => x.state == "available"),
|
||||
"Bikes occupied must return bikes which are either reserved or booked.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test consistency for a single sample set,
|
||||
/// </summary>
|
||||
/// <param name="p_oMemory"></param>
|
||||
private void VerifyBikeIdIsUnique(CopriCallsMemory p_oMemory)
|
||||
{
|
||||
Dictionary<string, BikeInfoBase> l_oChecker = new Dictionary<string, BikeInfoBase>();
|
||||
|
||||
var l_oBikesAvailable = p_oMemory.GetBikesAvailableAsync().Result;
|
||||
foreach (var l_oBike in l_oBikesAvailable.bikes.Values)
|
||||
{
|
||||
Assert.IsFalse(
|
||||
l_oChecker.Keys.Contains(l_oBike.bike),
|
||||
string.Format(
|
||||
"Bike form available bikes with id {0} already exist in dictionary. Sample set is {1}, stage index {2}.",
|
||||
l_oBike.bike,
|
||||
p_oMemory.ActiveSampleSet,
|
||||
p_oMemory.ActiveStageIndex));
|
||||
|
||||
l_oChecker.Add(l_oBike.bike, l_oBike);
|
||||
}
|
||||
|
||||
var l_oBikesOccupied = p_oMemory.GetBikesOccupiedAsync().Result;
|
||||
foreach (var l_oBike in l_oBikesOccupied.bikes_occupied.Values)
|
||||
{
|
||||
Assert.IsFalse(
|
||||
l_oChecker.Keys.Contains(l_oBike.bike),
|
||||
string.Format(
|
||||
"Bike from occupied bikes with id {0} already exist in dictionary. Sample set is {1}, stage index {2}.",
|
||||
l_oBike.bike,
|
||||
p_oMemory.ActiveSampleSet,
|
||||
p_oMemory.ActiveStageIndex));
|
||||
l_oChecker.Add(l_oBike.bike, l_oBike);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Request
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCopriCallsStatic
|
||||
{
|
||||
[Test]
|
||||
public void TestDeserializeObjectBikesAvailableValidResponse()
|
||||
{
|
||||
const string VALID_RESPONSE = @"
|
||||
{
|
||||
""shareejson"": {
|
||||
|
||||
""authcookie"": 0,
|
||||
""apiserver"": ""https://tinkwwp.copri-bike.de"",
|
||||
""response"": ""bikes_available"",
|
||||
""bikes"": {
|
||||
""3399"": {
|
||||
""description"": ""Cargo Trike"",
|
||||
""bike"": ""26"",
|
||||
""state"": ""available"",
|
||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
|
||||
""station"" : ""4""
|
||||
|
||||
},
|
||||
},
|
||||
""response_state"": ""OK"",
|
||||
""copri_version"" : ""4.1.0.0""
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
// Ensure that answer holds a valid bike.
|
||||
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(VALID_RESPONSE).bikes.FirstOrDefault().Value;
|
||||
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
|
||||
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
|
||||
Assert.AreEqual(l_oBike.bike, "26");
|
||||
Assert.That(
|
||||
l_oBike.station,
|
||||
Is.EqualTo("4"),
|
||||
"Station index must never be negative");
|
||||
Assert.AreEqual("available", l_oBike.state);
|
||||
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserializeObjectBikesAvailableValidResponse_NoDescription()
|
||||
{
|
||||
const string INVALID_RESPONSE = @"
|
||||
{
|
||||
""shareejson"": {
|
||||
|
||||
""authcookie"": 0,
|
||||
""apiserver"": ""https://tinkwwp.copri-bike.de"",
|
||||
""response"": ""bikes_available"",
|
||||
""bikes"": {
|
||||
""3399"": {
|
||||
""bike"": 26,
|
||||
""state"": ""available"",
|
||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
|
||||
""station"" : 4
|
||||
|
||||
},
|
||||
},
|
||||
""response_state"": ""OK"",
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
// Ensure that answer holds a valid bike.
|
||||
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(INVALID_RESPONSE).bikes.FirstOrDefault().Value;
|
||||
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
|
||||
Assert.IsNull(l_oBike.description);
|
||||
Assert.That(l_oBike.bike, Is.Not.Null);
|
||||
Assert.That(l_oBike.station, Is.Not.Null);
|
||||
Assert.AreEqual("available", l_oBike.state);
|
||||
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserializeObjectBikesAvailableValidResponse_NoBikeId()
|
||||
{
|
||||
const string VALID_RESPONSE = @"
|
||||
{
|
||||
""shareejson"": {
|
||||
|
||||
""authcookie"": 0,
|
||||
""apiserver"": ""https://tinkwwp.copri-bike.de"",
|
||||
""response"": ""bikes_available"",
|
||||
""bikes"": {
|
||||
""3399"": {
|
||||
""description"": ""Cargo Trike"",
|
||||
""state"": ""available"",
|
||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
|
||||
""station"" : ""4""
|
||||
},
|
||||
},
|
||||
""response_state"": ""OK"",
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
}
|
||||
}";
|
||||
|
||||
// Ensure that answer holds a valid bike.
|
||||
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(VALID_RESPONSE).bikes.FirstOrDefault().Value;
|
||||
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
|
||||
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
|
||||
Assert.That(l_oBike.bike, Is.Null);
|
||||
Assert.That(l_oBike.station, Is.Not.Null);
|
||||
Assert.AreEqual("available", l_oBike.state);
|
||||
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeserializeObjectBikesOccupiedValidResponse()
|
||||
{
|
||||
const string VALID_RESPONSE = @"
|
||||
{
|
||||
""shareejson"": {
|
||||
""response_state"": ""OK"",
|
||||
""bikes_occupied"": {
|
||||
""87781"": {
|
||||
""timeCode"": ""3630"",
|
||||
""state"": ""occupied"",
|
||||
""station"" : ""5"",
|
||||
""description"": ""Cargo Long"",
|
||||
""start_time"": ""2017-11-28 11:01:51.637747+01"",
|
||||
""bike"": ""8""
|
||||
},
|
||||
""87782"": {
|
||||
""timeCode"": ""2931"",
|
||||
""state"": ""occupied"",
|
||||
""station"" : ""4"",
|
||||
""description"": ""Cargo Long"",
|
||||
""start_time"": ""2017-11-28 13:06:55.147368+01"",
|
||||
""bike"": ""7""
|
||||
}
|
||||
},
|
||||
""authcookie"": ""b76b97e43a2d76b8499f32e6dd597af8"",
|
||||
""response"": ""user_bikes_occupied"",
|
||||
""apiserver"": ""https://tinkwwp.copri-bike.de"",
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
}
|
||||
}";
|
||||
|
||||
// Ensure that answer holds a valid bike.
|
||||
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesReservedOccupiedResponse>(VALID_RESPONSE).bikes_occupied.FirstOrDefault().Value;
|
||||
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
|
||||
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
|
||||
Assert.That(l_oBike.bike, Is.Not.Null);
|
||||
Assert.That(l_oBike.station, Is.Not.Null);
|
||||
Assert.Greater(l_oBike.state.Length, 0, "State info must never be null or empty.");
|
||||
// Todo: Requested bikes do not have a gps position. What is about booked bikes?
|
||||
// Assert.Greater(l_oBike.gps.Length, 0, "Gps position must never be empty.");
|
||||
Assert.Greater(l_oBike.start_time.Length, 0, "Time when request/ booking was performed must never be null or empty.");
|
||||
Assert.Greater(l_oBike.timeCode.Length, 0, "Booking code must never be null or empty.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCopriServerUriList
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oUri = new CopriServerUriList();
|
||||
|
||||
Assert.Greater(l_oUri.Uris.Count, 0, "There must be at least one uri");
|
||||
Assert.NotNull(l_oUri.ActiveUri);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_AryStringString()
|
||||
{
|
||||
var l_oUri = new CopriServerUriList(
|
||||
(new List<Uri> { new Uri("http://1.2.3.4"), new Uri("http://2.3.4.5"), new Uri("http://3.4.5.6") }).ToArray(),
|
||||
new Uri("http://2.3.4.5"));
|
||||
|
||||
Assert.AreEqual(3, l_oUri.Uris.Count);
|
||||
Assert.AreEqual(new Uri("http://2.3.4.5"), l_oUri.ActiveUri);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_AryStringString_NullList()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new CopriServerUriList(
|
||||
null,
|
||||
new Uri("http://2.3.4.5")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_AryStringString_InvalidList()
|
||||
{
|
||||
Assert.Throws<ArgumentException>( () => new CopriServerUriList(
|
||||
(new List<Uri>()).ToArray(),
|
||||
new Uri("http://2.3.4.5")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_AryStringString_InvalidActiveUri()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new CopriServerUriList(
|
||||
(new List<Uri> { new Uri("http://1.2.3.4"), new Uri("http://2.3.4.5"), new Uri("http://3.4.5.6") }).ToArray(),
|
||||
new Uri("http://9.9.9.9")));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestDefaultActiveUri()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"https://shareeapp-primary.copri.eu/APIjsonserver",
|
||||
CopriServerUriList.DefaultActiveUri.AbsoluteUri,
|
||||
"In production environment, server address must always be app.tink-konstanz.de/APIjsonserver.");
|
||||
}
|
||||
}
|
||||
}
|
94
TestTINKLib/Fixtures/ObjectTests/Connector/TestFilter.cs
Normal file
94
TestTINKLib/Fixtures/ObjectTests/Connector/TestFilter.cs
Normal file
|
@ -0,0 +1,94 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.Connector;
|
||||
using System.Linq;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
/// <summary> Tests filter object. </summary>
|
||||
[TestFixture]
|
||||
public class TestFilter
|
||||
{
|
||||
/// <summary> Tests all stations. </summary>
|
||||
[Test]
|
||||
public void TestGetStationsAll()
|
||||
{
|
||||
var l_oConnector = new ConnectorCache(
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
new CopriCallsMemory(CopriCallsMemory.SampleSets.Set2, 1));
|
||||
|
||||
var l_oFilter = new FilteredConnector(new List<string> { "TINK", "Konrad" }, l_oConnector);
|
||||
var l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
|
||||
Assert.AreEqual(9, l_oStations.StationsAll.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string> { "TINK" }, l_oConnector);
|
||||
l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
|
||||
Assert.AreEqual(8, l_oStations.StationsAll.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string> { "Konrad" }, l_oConnector);
|
||||
l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
|
||||
Assert.AreEqual(2, l_oStations.StationsAll.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string> { "AGroupNamedNonsensDoesNotExist" }, l_oConnector);
|
||||
l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
|
||||
Assert.AreEqual(0, l_oStations.StationsAll.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string>(), l_oConnector);
|
||||
l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
|
||||
Assert.AreEqual(9, l_oStations.StationsAll.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(null, l_oConnector);
|
||||
l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
|
||||
Assert.AreEqual(9, l_oStations.StationsAll.Count(), "Null means filter none.");
|
||||
}
|
||||
|
||||
/// <summary> Tests all stations. </summary>
|
||||
[Test]
|
||||
public void TestGetBikesAll()
|
||||
{
|
||||
var l_oConnector = new ConnectorCache(
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
new CopriCallsMemory(CopriCallsMemory.SampleSets.Set2, 1));
|
||||
|
||||
var l_oFilter = new FilteredConnector(new List<string> { "TINK", "Konrad" }, l_oConnector);
|
||||
var l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
|
||||
Assert.AreEqual(12, l_oBikes.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string> { "TINK" }, l_oConnector);
|
||||
l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
|
||||
Assert.AreEqual(11, l_oBikes.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string> { "Konrad" }, l_oConnector);
|
||||
l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
|
||||
Assert.AreEqual(1, l_oBikes.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string> { "AGroupNamedNonsensDoesNotExist" }, l_oConnector);
|
||||
l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
|
||||
Assert.AreEqual(0, l_oBikes.Count());
|
||||
|
||||
l_oFilter = new FilteredConnector(new List<string>(), l_oConnector);
|
||||
l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
|
||||
Assert.AreEqual(12, l_oBikes.Count(), "List with zero element means filter all.");
|
||||
|
||||
l_oFilter = new FilteredConnector(null, l_oConnector);
|
||||
l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
|
||||
Assert.AreEqual(12, l_oBikes.Count(), "Null means filter none.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsConnected()
|
||||
{
|
||||
var l_oMock = MockRepository.GenerateMock<IConnector>();
|
||||
l_oMock.Expect(x => x.IsConnected).Return(true) ;
|
||||
Assert.IsTrue(new FilteredConnector(new List<string>(), l_oMock).IsConnected);
|
||||
|
||||
l_oMock = MockRepository.GenerateMock<IConnector>();
|
||||
l_oMock.Expect(x => x.IsConnected).Return(false);
|
||||
Assert.IsFalse(new FilteredConnector(new List<string>(), l_oMock).IsConnected);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,615 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
using JsonConvertRethrow = TINK.Repository.Response.JsonConvertRethrow;
|
||||
|
||||
namespace TestTINKLib.Fixtures.Connector
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestTextToTypeHelper
|
||||
{
|
||||
[Test]
|
||||
public void TestGetWheelType_InvalidDescription()
|
||||
{
|
||||
var l_oInfo = new BikeInfoBase();
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.IsNull(l_oInfo.description);
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.IsNull(TextToTypeHelper.GetWheelType(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetWheelType()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""2"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""description"" : ""Cargo Long"",
|
||||
""gps"" : { ""latitude"": ""47.6612083333"", ""longitude"": ""9.16637533333"" },
|
||||
""station"" : ""9"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(WheelType.Two, TextToTypeHelper.GetWheelType(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""11"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""description"" : ""Cargo Trike"",
|
||||
""gps"" : { ""latitude"": ""47.665051"", ""longitude"": ""9.174096"" },
|
||||
""station"" : ""1"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(WheelType.Trike, TextToTypeHelper.GetWheelType(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""51"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""description"" : ""Demo Stadtrad"",
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""station"" : ""8"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(WheelType.Two, TextToTypeHelper.GetWheelType(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""51"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""description"" : ""Stadtrad"",
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""station"" : ""8"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(WheelType.Two, TextToTypeHelper.GetWheelType(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetTypeOfBike_InvalidDescription()
|
||||
{
|
||||
var l_oInfo = new BikeInfoBase();
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.IsNull(l_oInfo.description);
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.IsNull(TextToTypeHelper.GetTypeOfBike(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetTypeOfBike()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""2"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""description"" : ""Cargo Long"",
|
||||
""gps"" : { ""latitude"": ""47.6612083333"", ""longitude"": ""9.16637533333"" },
|
||||
""station"" : ""9"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(TypeOfBike.Cargo, TextToTypeHelper.GetTypeOfBike(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""11"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""description"" : ""Cargo Trike"",
|
||||
""gps"" : { ""latitude"": ""47.665051"", ""longitude"": ""9.174096"" },
|
||||
""station"" : ""1"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(TypeOfBike.Cargo, TextToTypeHelper.GetTypeOfBike(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""51"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""description"" : ""Demo Stadtrad"",
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""station"" : ""8"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(TypeOfBike.Citybike, TextToTypeHelper.GetTypeOfBike(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""51"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""description"" : ""Stadtrad"",
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""station"" : ""8"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.AreEqual(TypeOfBike.Citybike, TextToTypeHelper.GetTypeOfBike(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetState_InvalidDescription()
|
||||
{
|
||||
var l_oInfo = new BikeInfoBase();
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.IsNull(l_oInfo.state);
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.Throws<InvalidResponseException<BikeInfoBase>>(() => TextToTypeHelper.GetState(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetIsDemo()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""2"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""description"" : ""Cargo Long"",
|
||||
""gps"" : { ""latitude"": ""47.6612083333"", ""longitude"": ""9.16637533333"" },
|
||||
""station"" : ""9"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.IsFalse(TextToTypeHelper.GetIsDemo(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""11"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""description"" : ""Cargo Trike"",
|
||||
""gps"" : { ""latitude"": ""47.665051"", ""longitude"": ""9.174096"" },
|
||||
""station"" : ""1"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.IsFalse(TextToTypeHelper.GetIsDemo(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""51"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""description"" : ""Demo Stadtrad"",
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""station"" : ""8"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.IsTrue(TextToTypeHelper.GetIsDemo(l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(@"
|
||||
{
|
||||
""bike"" : ""51"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""description"" : ""Stadtrad"",
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""station"" : ""8"",
|
||||
""state"" : ""available""
|
||||
}");
|
||||
|
||||
// Verify behaviour of member.
|
||||
Assert.IsFalse(TextToTypeHelper.GetIsDemo(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetPosition()
|
||||
{
|
||||
Assert.AreEqual(1.234d, TextToTypeHelper.GetPosition(JsonConvert.DeserializeObject<GpsInfo>("{ \"latitude\" : \"1.234\", \"longitude\" : \"5.678\"}")).Latitude);
|
||||
Assert.AreEqual(5.678d, TextToTypeHelper.GetPosition(JsonConvert.DeserializeObject<GpsInfo>("{ \"latitude\" : \"1.234\", \"longitude\" : \"5.678\"}")).Longitude);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetStationGroup_Invalid()
|
||||
{
|
||||
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAllResponse.StationInfo>(
|
||||
@"{
|
||||
""station"" : ""4"",
|
||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" }
|
||||
}");
|
||||
|
||||
// From COPRI version v4.1 no more exception thrown.
|
||||
Assert.That(l_oStation.GetGroup().Count(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetStationGroup_TINK()
|
||||
{
|
||||
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAllResponse.StationInfo>(
|
||||
@"{
|
||||
""station"" : ""4"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" }
|
||||
}");
|
||||
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oStation.GetGroup().ToArray()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetStationGroup_TINKAndKonrad()
|
||||
{
|
||||
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAllResponse.StationInfo>(
|
||||
@"{
|
||||
""station"" : ""4"",
|
||||
""station_group"": [ ""TINK"", ""Konrad"" ],
|
||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" }
|
||||
}");
|
||||
|
||||
Assert.AreEqual("TINK,Konrad", string.Join(",", l_oStation.GetGroup().ToArray()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikeGroup_TINK()
|
||||
{
|
||||
var l_oBike = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(
|
||||
@"{
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""18"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""station"" : ""13"",
|
||||
}");
|
||||
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oBike.GetGroup().ToArray()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikeGroup_TINKCopri()
|
||||
{
|
||||
var l_oBike = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(
|
||||
@"{
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""18"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""system"" : ""BC"",
|
||||
""station"" : ""13"",
|
||||
}");
|
||||
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oBike.GetGroup().ToArray()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikeGroup_TINKSMS()
|
||||
{
|
||||
var l_oBike = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(
|
||||
@"{
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""18"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""system"" : ""Lock"",
|
||||
""station"" : ""13"",
|
||||
}");
|
||||
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oBike.GetGroup().ToArray()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikeGroup_Konrad()
|
||||
{
|
||||
var l_oBike = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(
|
||||
@"{
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""18"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike_group"" : [ ""Konrad"" ],
|
||||
""station"" : ""13"",
|
||||
}");
|
||||
|
||||
Assert.AreEqual("Konrad", string.Join(",", l_oBike.GetGroup().ToArray()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBikeGroup_Null()
|
||||
{
|
||||
var l_oBike = JsonConvertRethrow.DeserializeObject<BikeInfoBase>(
|
||||
@"{
|
||||
""state"" : ""available"",
|
||||
""bike"" : ""18"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""station"" : ""13"",
|
||||
}");
|
||||
|
||||
Assert.AreEqual(0, l_oBike.GetGroup().ToArray().Length);
|
||||
}
|
||||
[Test]
|
||||
public void TestGetAuthGroup()
|
||||
{
|
||||
var l_oResponse = JsonConvertRethrow.DeserializeObject<AuthorizationResponse>(@"
|
||||
{
|
||||
""response"" : ""authorization"",
|
||||
""authcookie"" : ""4da3044c8657a04ba60e2eaa753bc51a"",
|
||||
""user_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(2, l_oResponse.GetGroup().ToList().Count);
|
||||
Assert.AreEqual(FilterHelper.FILTERTINKGENERAL, l_oResponse.GetGroup().ToList()[0]);
|
||||
Assert.AreEqual("Konrad", l_oResponse.GetGroup().ToList()[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetGroupString()
|
||||
{
|
||||
// From COPRI version v4.1 no more exception thrown.
|
||||
Assert.That(TextToTypeHelper.GetGroup(new string[0]).Count(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetGroupString_Null()
|
||||
{
|
||||
// From COPRI version v4.1 no more exception thrown.
|
||||
Assert.That(TextToTypeHelper.GetGroup((string[])null).Count(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetGroupString_Roundtrip()
|
||||
{
|
||||
Assert.AreEqual("Tunk,Unk", TextToTypeHelper.GetGroup(TextToTypeHelper.GetGroup(new [] { "Tunk", "Unk" })));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetUserKey()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
""total_price"": ""0.00"",
|
||||
""gps"" : { ""latitude"": ""47.6586133"", ""longitude"": ""9.16864"" },
|
||||
""unit_price"": ""3.00"",
|
||||
""K_u"": ""[99, 104, 120, 121, 63, 99, -10, -110, 94, 70, 15, -112, -6, 101, 117, -90, -113, -54, -90, -95, 0, 0, 0, 0]"",
|
||||
""tariff_description"": {""name"" : ""TINK Basic""},
|
||||
""end_time"": ""2020-04-07 16:55:18"",
|
||||
""K_seed"": ""[-18, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
|
||||
""system"": ""Ilockit"",
|
||||
""bike"": ""16"",
|
||||
""computed_hours"": ""0"",
|
||||
""request_time"": ""2020-04-07 16:55:06.823436+02"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""K_a"": ""[-19, 29, -60, 29, 35, -121, -69, 93, 27, -122, 107, -127, -30, 74, 82, 12, 4, -20, 40, 16, 0, 0, 0, 0]"",
|
||||
""state"": ""occupied"",
|
||||
""real_hours"": ""0"",
|
||||
""station"" : ""7"",
|
||||
""start_time"": ""2020-04-07 16:55:17.786551+02"",
|
||||
""description"": ""Cargo Long""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(
|
||||
99,
|
||||
TextToTypeHelper.GetUserKey(l_oInfo)[0]);
|
||||
Assert.AreEqual(
|
||||
104,
|
||||
TextToTypeHelper.GetUserKey(l_oInfo)[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetAdminKey()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
""total_price"": ""0.00"",
|
||||
""gps"" : { ""latitude"": ""47.6586133"", ""longitude"": ""9.16864"" },
|
||||
""unit_price"": ""3.00"",
|
||||
""K_u"": ""[99, 104, 120, 121, 63, 99, -10, -110, 94, 70, 15, -112, -6, 101, 117, -90, -113, -54, -90, -95, 0, 0, 0, 0]"",
|
||||
""tariff_description"": {""name"" : ""TINK Basic""},
|
||||
""end_time"": ""2020-04-07 16:55:18"",
|
||||
""K_seed"": ""[-18, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
|
||||
""system"": ""Ilockit"",
|
||||
""bike"": ""16"",
|
||||
""computed_hours"": ""0"",
|
||||
""request_time"": ""2020-04-07 16:55:06.823436+02"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""K_a"": ""[-19, 29, -60, 29, 35, -121, -69, 93, 27, -122, 107, -127, -30, 74, 82, 12, 4, -20, 40, 16, 0, 0, 0, 0]"",
|
||||
""state"": ""occupied"",
|
||||
""real_hours"": ""0"",
|
||||
""station"" : ""7"",
|
||||
""start_time"": ""2020-04-07 16:55:17.786551+02"",
|
||||
""description"": ""Cargo Long""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(
|
||||
237,
|
||||
TextToTypeHelper.GetAdminKey(l_oInfo)[0]);
|
||||
Assert.AreEqual(
|
||||
29,
|
||||
TextToTypeHelper.GetAdminKey(l_oInfo)[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetSeed()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
""total_price"": ""0.00"",
|
||||
""gps"" : { ""latitude"": ""47.6586133"", ""longitude"": ""9.16864"" },
|
||||
""unit_price"": ""3.00"",
|
||||
""K_u"": ""[99, 104, 120, 121, 63, 99, -10, -110, 94, 70, 15, -112, -6, 101, 117, -90, -113, -54, -90, -95, 0, 0, 0, 0]"",
|
||||
""tariff_description"": {""name"" : ""TINK Basic""},
|
||||
""end_time"": ""2020-04-07 16:55:18"",
|
||||
""K_seed"": ""[-18, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
|
||||
""system"": ""Ilockit"",
|
||||
""bike"": ""16"",
|
||||
""computed_hours"": ""0"",
|
||||
""request_time"": ""2020-04-07 16:55:06.823436+02"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""K_a"": ""[-19, 29, -60, 29, 35, -121, -69, 93, 27, -122, 107, -127, -30, 74, 82, 12, 4, -20, 40, 16, 0, 0, 0, 0]"",
|
||||
""state"": ""occupied"",
|
||||
""real_hours"": ""0"",
|
||||
""station"" : ""7"",
|
||||
""start_time"": ""2020-04-07 16:55:17.786551+02"",
|
||||
""description"": ""Cargo Long""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(
|
||||
238,
|
||||
TextToTypeHelper.GetSeed(l_oInfo)[0]);
|
||||
Assert.AreEqual(
|
||||
176,
|
||||
TextToTypeHelper.GetSeed(l_oInfo)[1]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetSeedUserKeyAdminKey_Invalid()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
""total_price"": ""0.00"",
|
||||
""gps"" : { ""latitude"": ""47.6586133"", ""longitude"": ""9.16864"" },
|
||||
""unit_price"": ""3.00"",
|
||||
""K_u"": ""[]"",
|
||||
""tariff_description"": {""name"" : ""TINK Basic""},
|
||||
""end_time"": ""2020-04-07 16:55:18"",
|
||||
""K_seed"": ""[-18a, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
|
||||
""system"": ""Ilockit"",
|
||||
""bike"": ""16"",
|
||||
""computed_hours"": ""0"",
|
||||
""request_time"": ""2020-04-07 16:55:06.823436+02"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""K_a"": ""{-19, 29, -60, 29, 35, -121, -69, 93, 27, -122, 107, -127, -30, 74, 82, 12, 4, -20, 40, 16, 0, 0, 0, 0}"",
|
||||
""state"": ""occupied"",
|
||||
""real_hours"": ""0"",
|
||||
""station"" : ""7"",
|
||||
""start_time"": ""2020-04-07 16:55:17.786551+02"",
|
||||
""description"": ""Cargo Long""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
TextToTypeHelper.GetSeed(l_oInfo).Length);
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
TextToTypeHelper.GetUserKey(l_oInfo).Length);
|
||||
|
||||
Assert.AreEqual(
|
||||
0,
|
||||
TextToTypeHelper.GetAdminKey(l_oInfo).Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBluetoothLockId_FromBikeInfo_Invalid()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
}");
|
||||
|
||||
Assert.AreEqual(0, TextToTypeHelper.GetBluetoothLockId (l_oInfo));
|
||||
|
||||
l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
""Ilockit_ID"": """"
|
||||
}");
|
||||
|
||||
Assert.AreEqual(0, TextToTypeHelper.GetBluetoothLockId(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBluetoothLockId_FromBikeInfo()
|
||||
{
|
||||
var l_oInfo = JsonConvertRethrow.DeserializeObject<BikeInfoReservedOrBooked>(@"
|
||||
{
|
||||
""Ilockit_ID"": ""ISHAREIT-132""
|
||||
}");
|
||||
|
||||
Assert.AreEqual(
|
||||
132,
|
||||
TextToTypeHelper.GetBluetoothLockId(l_oInfo));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBluetoothLockId_FromString_Invalid()
|
||||
{
|
||||
Assert.AreEqual(0, TextToLockItTypeHelper.GetBluetoothLockId((string)null));
|
||||
Assert.AreEqual(0, TextToLockItTypeHelper.GetBluetoothLockId(""));
|
||||
|
||||
Assert.AreEqual(0, TextToLockItTypeHelper.GetBluetoothLockId("HubbaBubba"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBluetoothLockId_FromString()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
132,
|
||||
TextToLockItTypeHelper.GetBluetoothLockId("ISHAREIT-132"));
|
||||
|
||||
Assert.AreEqual(
|
||||
132,
|
||||
TextToLockItTypeHelper.GetBluetoothLockId("ISHAREIT+132"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetCopriVersion()
|
||||
{
|
||||
var version = JsonConvertRethrow.DeserializeObject<CopriVersion>(@"
|
||||
{
|
||||
""copri_version"": ""4.3.2.1""
|
||||
}");
|
||||
|
||||
Assert.That(
|
||||
version.GetCopriVersion(),
|
||||
Is.EqualTo(new Version(4,3,2,1)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetCopriVersion_Invald()
|
||||
{
|
||||
var version = JsonConvertRethrow.DeserializeObject<CopriVersion>(@"
|
||||
{
|
||||
""copri_version"": ""hellO""
|
||||
}");
|
||||
|
||||
Assert.That(
|
||||
() => version.GetCopriVersion(),
|
||||
Throws.InstanceOf<InvalidResponseException>());
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestGetCopriVersion_Null()
|
||||
{
|
||||
|
||||
Assert.That(
|
||||
() => TextToTypeHelper.GetCopriVersion(null),
|
||||
Throws.InstanceOf<InvalidResponseException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetCopriVersion_NotContained()
|
||||
{
|
||||
var version = JsonConvertRethrow.DeserializeObject<CopriVersion>(@"
|
||||
{
|
||||
}");
|
||||
|
||||
Assert.That(
|
||||
() => version.GetCopriVersion(),
|
||||
Throws.InstanceOf<InvalidResponseException>());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.Logging;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLoggingDirectoryManager
|
||||
{
|
||||
[Test]
|
||||
public void TestConstructInvalidArgs()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(
|
||||
() => new LoggingDirectoryManager(
|
||||
(name) => new List<string> { "2018_02_06_22_18_00" /* oldest */, "2018_02_06_23_10_00" /*youngest*/ , "2018_02_06_22_19_00", "2018_02_06_22_20_00" },
|
||||
(name) => false,
|
||||
(name) => { },
|
||||
(name) => { },
|
||||
"abc",
|
||||
'\\',
|
||||
0));
|
||||
|
||||
Assert.Throws<ArgumentException>(
|
||||
() => new LoggingDirectoryManager(
|
||||
(name) => new List<string> { "2018_02_06_22_18_00" /* oldest */, "2018_02_06_23_10_00" /*youngest*/ , "2018_02_06_22_19_00", "20180206222000" },
|
||||
(name) => false,
|
||||
(name) => { },
|
||||
(name) => { },
|
||||
"",
|
||||
'\\',
|
||||
3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeleteObsoleteLogs()
|
||||
{
|
||||
var l_oDeletedFilesList = new List<string>();
|
||||
|
||||
var l_oManger = new LoggingDirectoryManager(
|
||||
(name) => new List<string> { "2018_02_06_22_18_00" /* oldest */, "2018_02_06_23_10_00" /*youngest*/ , "2018_02_06_22_19_00", "20180206222000" },
|
||||
(name) => false,
|
||||
(name) => { },
|
||||
(name) => { l_oDeletedFilesList.Add(name); },
|
||||
"abc",
|
||||
'\\',
|
||||
3);
|
||||
|
||||
l_oManger.DeleteObsoleteLogs();
|
||||
|
||||
Assert.AreEqual(2, l_oDeletedFilesList.Count);
|
||||
Assert.IsTrue(l_oDeletedFilesList.Contains("2018_02_06_22_18_00"));
|
||||
Assert.IsTrue(l_oDeletedFilesList.Contains("2018_02_06_22_19_00"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDeleteObsoleteLogs_EmptyDirectory()
|
||||
{
|
||||
var l_oDeletedFilesList = new List<string>();
|
||||
|
||||
var l_oManger = new LoggingDirectoryManager(
|
||||
(name) => new List<string>(),
|
||||
(name) => false,
|
||||
(name) => { },
|
||||
(name) => { l_oDeletedFilesList.Add(name); },
|
||||
"abc",
|
||||
'\\',
|
||||
3);
|
||||
|
||||
l_oManger.DeleteObsoleteLogs();
|
||||
|
||||
Assert.AreEqual(0, l_oDeletedFilesList.Count);
|
||||
}
|
||||
}
|
||||
}
|
43
TestTINKLib/Fixtures/ObjectTests/Map/TestMapPageFilter.cs
Normal file
43
TestTINKLib/Fixtures/ObjectTests/Map/TestMapPageFilter.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model;
|
||||
using TINK.ViewModel.Map;
|
||||
|
||||
namespace UITest.Fixtures.ObjectTests.Map
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestMapPageFilter
|
||||
{
|
||||
[Test]
|
||||
public void TestCurrentFilter_Empty()
|
||||
{
|
||||
var l_oFilter = new TinkKonradToggleViewModel(null);
|
||||
Assert.IsEmpty(l_oFilter.CurrentFilter);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCurrentFilter()
|
||||
{
|
||||
var l_oFilter = new TinkKonradToggleViewModel(new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }));
|
||||
|
||||
Assert.AreEqual("TINK", l_oFilter.CurrentFilter);
|
||||
|
||||
l_oFilter = new TinkKonradToggleViewModel(new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }));
|
||||
|
||||
Assert.AreEqual("Konrad", l_oFilter.CurrentFilter);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsToggleVisible()
|
||||
{
|
||||
var l_oFilter = new TinkKonradToggleViewModel(new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On } }));
|
||||
|
||||
Assert.IsFalse(l_oFilter.IsToggleVisible);
|
||||
|
||||
l_oFilter = new TinkKonradToggleViewModel(new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }));
|
||||
|
||||
Assert.IsTrue(l_oFilter.IsToggleVisible);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Repository.Request;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Model.Repository.Request
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestRequestBuilderLoggedIn
|
||||
{
|
||||
[Test]
|
||||
public void TestUpateLockingStateGeolocationIsNull()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.UpateLockingState("12", null, lock_state.locked, 15.03),
|
||||
Is.EqualTo("request=booking_update&bike=12&lock_state=locked&voltage=15.03&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpateLockingStateGeolocationIsNullBatteryPercentageIsNAN()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.UpateLockingState("12", null, lock_state.locked, double.NaN),
|
||||
Is.EqualTo("request=booking_update&bike=12&lock_state=locked&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpateLockingStateGeolocation_AccuraycyNull()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.UpateLockingState("12", new LocationDto.Builder { Latitude = 21, Longitude = 17, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(), lock_state.locked, 12),
|
||||
Is.EqualTo("request=booking_update&bike=12&gps=21,17&gps_age=0.07&lock_state=locked&voltage=12&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpateLockingStateGeolocation_AccuraycyNullBatteryPercentageIsNAN()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.UpateLockingState("12", new LocationDto.Builder { Latitude = 21, Longitude = 17, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(), lock_state.locked, double.NaN),
|
||||
Is.EqualTo("request=booking_update&bike=12&gps=21,17&gps_age=0.07&lock_state=locked&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpateLockingStateGeolocation()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.UpateLockingState("12", new LocationDto.Builder { Latitude = 21, Longitude = 17, Accuracy = 5.7, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(), lock_state.locked, 98),
|
||||
Is.EqualTo("request=booking_update&bike=12&gps=21,17&gps_accuracy=5.7&gps_age=0.07&lock_state=locked&voltage=98&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoReturnGeolocationIsNull()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoReturn("12", null, null),
|
||||
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoReturnGeolocation_AccuraycyNull()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoReturn(
|
||||
"12",
|
||||
new LocationDto.Builder { Latitude = 21, Longitude = 17, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(),
|
||||
null),
|
||||
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&gps=21,17&gps_age=0.07&lock_state=locked"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoReturnGeolocation()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoReturn(
|
||||
"12",
|
||||
new LocationDto.Builder { Latitude = 21, Longitude = 17, Accuracy = 5.7, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(),
|
||||
null),
|
||||
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&gps=21,17&gps_accuracy=5.7&gps_age=0.07&lock_state=locked"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoSubmitFeedback_Ok()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoSubmitFeedback("Radl22"),
|
||||
Is.EqualTo("request=user_feedback&bike=Radl22&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoSubmitFeedback_BikeBroken()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoSubmitFeedback("Cycle33", isBikeBroken: true),
|
||||
Is.EqualTo("request=user_feedback&bike=Cycle33&bike_broken=1&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoSubmitFeedback_Message()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoSubmitFeedback("Mühle", "Uno due tre"),
|
||||
Is.EqualTo("request=user_feedback&bike=Mühle&message=Uno+due+tre&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoSubmitFeedback_ErrorMessage()
|
||||
{
|
||||
var builder = new RequestBuilderLoggedIn("MyMeranctIt", "MySessionCookie");
|
||||
Assert.That(
|
||||
builder.DoSubmitFeedback("bike12","Uno due tre", true),
|
||||
Is.EqualTo("request=user_feedback&bike=bike12&bike_broken=1&message=Uno+due+tre&authcookie=MySessionCookieMyMeranctIt"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Repository.Exception;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Repository.Exception
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBookingDeclinedException
|
||||
{
|
||||
[Test]
|
||||
public void TestIsBookingDeclined()
|
||||
{
|
||||
const string responseText = "OK: BOOKING_REQUEST declined. Max count of 8 occupied bikes has been reached";
|
||||
|
||||
BookingDeclinedException exception = null;
|
||||
|
||||
Assert.That(() => BookingDeclinedException.IsBookingDeclined(responseText, out exception),
|
||||
Is.EqualTo(true));
|
||||
|
||||
Assert.That(() => exception.MaxBikesCount,
|
||||
Is.EqualTo(8));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsBookingDeclined_InvalidNumber()
|
||||
{
|
||||
const string responseText = "OK: BOOKING_REQUEST declined. Max count of 8 occupied bikes has been reached";
|
||||
|
||||
BookingDeclinedException exception = null;
|
||||
|
||||
Assert.That(() => BookingDeclinedException.IsBookingDeclined(responseText, out exception),
|
||||
Is.EqualTo(true));
|
||||
|
||||
Assert.That(() => exception.MaxBikesCount,
|
||||
Is.EqualTo(8));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Repository.Exception;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Repository.Exception
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestNoGPSDataException
|
||||
{
|
||||
[Test]
|
||||
public void TestIsNotAtStation()
|
||||
{
|
||||
const string responseText = "Failure 2245: No GPS data, state change forbidden.";
|
||||
|
||||
NoGPSDataException exception = null;
|
||||
|
||||
Assert.That(() => NoGPSDataException.IsNoGPSData(responseText, out exception),
|
||||
Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsNotAtStation_InvalidNr()
|
||||
{
|
||||
const string responseText = "Failure 2248: No GPS data, state change forbidden.";
|
||||
|
||||
NoGPSDataException exception = null;
|
||||
|
||||
Assert.That(() => NoGPSDataException.IsNoGPSData(responseText, out exception),
|
||||
Is.EqualTo(false));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Repository.Exception;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Repository.Exception
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestNotAtStationException
|
||||
{
|
||||
[Test]
|
||||
public void TestIsNotAtStation()
|
||||
{
|
||||
const string responseText = "Failure 2178: bike 1545 out of GEO fencing. 15986 meter distance to next station 105. OK: bike 1545 locked confirmed";
|
||||
|
||||
NotAtStationException exception = null;
|
||||
|
||||
Assert.That(() => NotAtStationException.IsNotAtStation(responseText, out exception),
|
||||
Is.EqualTo(true));
|
||||
|
||||
Assert.That(() => exception.StationNr,
|
||||
Is.EqualTo(105));
|
||||
|
||||
Assert.That(() => exception.Distance,
|
||||
Is.EqualTo(15986));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsNotAtStation_InvalidNr()
|
||||
{
|
||||
const string responseText = "Failure 2177: bike 1545 out of GEO fencing. 15986 meter distance to next station 105. OK: bike 1545 locked confirmed";
|
||||
|
||||
NotAtStationException exception = null;
|
||||
|
||||
Assert.That(() => NotAtStationException.IsNotAtStation(responseText, out exception),
|
||||
Is.EqualTo(false));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TINK.Services.BluetoothLock.Crypto;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Services.BluetoothLock.Crypto
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCryptoHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures that decyption from haveltec- lib produces the same results than sharee lib.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Test_DecryptStringFromBytes_Aes()
|
||||
{
|
||||
// keyCopri (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
var keyCopri = (new sbyte[] { -6, 53, 29, -112, 7, -83, -41, -7, 30, 45, -13, -2, -108, -29, -90, 71, 15, -74, -76, 32, 0, 0, 0, 0 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// Encrypted seed value from lock (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
var seedLockEnc = (new sbyte[] { 50, 51, -40, 64, 42, 82, 97, -24, 20, -39, -15, 126, 119, -110, 47, -18 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// Decrypted seed value from lock (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
var acces_key = (new sbyte[] { 19, -66, 55, 18, -106, -92, 70, -40, 117, -87, -19, 124, 19, 54, -18, -82 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
var decrypt = new Cipher().Decrypt(keyCopri, seedLockEnc);
|
||||
|
||||
Assert.IsTrue(acces_key.SequenceEqual(decrypt));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestGetSeedLock()
|
||||
{
|
||||
// seed copri (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] seedCopri = (new sbyte[] { -7, -69, 16, -52, 88, 38, -92, 82, -99, -79, 19, 16, -41, -127, 51, 24 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// keyCopri (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] keyCopri = (new sbyte[] { -6, 53, 29, -112, 7, -83, -41, -7, 30, 45, -13, -2, -108, -29, -90, 71, 15, -74, -76, 32, 0, 0, 0, 0 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// Encrypted seed value from lock (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] seedLockEnc = (new sbyte[] { 92, 80, -36, -2, 101, -31, -23, -43, 71, 62, 126, -70, 54, -53, -119, -56 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
//// Decryped seed value? access values? from lock (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] seedLockDec = (new sbyte[] { 62, -51, 96, -80, 7, -84, 48, -104, 47, 51, -22, -23, 30, -10, -88, -97 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
var crypto = new AuthCryptoHelper(
|
||||
seedLockEnc,
|
||||
keyCopri,
|
||||
null);
|
||||
|
||||
var result = crypto.GetSeedLock();
|
||||
|
||||
Assert.IsTrue(seedLockDec.SequenceEqual(result));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestGetAccessKeyEncrypted()
|
||||
{
|
||||
// seed copri (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] seedCopri = (new sbyte[] { -7, -69, 16, -52, 88, 38, -92, 82, -99, -79, 19, 16, -41, -127, 51, 24 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// keyCopri (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] keyCopri = (new sbyte[] { -6, 53, 29, -112, 7, -83, -41, -7, 30, 45, -13, -2, -108, -29, -90, 71, 15, -74, -76, 32, 0, 0, 0, 0 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// Encrypted seed value from lock (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] seedLockEnc = (new sbyte[] { 92, 80, -36, -2, 101, -31, -23, -43, 71, 62, 126, -70, 54, -53, -119, -56 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
// Decryped seed value? access values? from lock (value copied from debugging session of sharing_ble_lib/ haveltec code)
|
||||
byte[] seedLockDec = (new sbyte[] { 62, -51, 96, -80, 7, -84, 48, -104, 47, 51, -22, -23, 30, -10, -88, -97 }).Select(x => (byte)x).ToArray();
|
||||
|
||||
var crypto = new AuthCryptoHelper(
|
||||
seedLockEnc,
|
||||
keyCopri,
|
||||
null);
|
||||
|
||||
var result = crypto.GetSeedLock();
|
||||
|
||||
Assert.AreEqual(
|
||||
Encoding.UTF8.GetString(seedLockDec),
|
||||
Encoding.UTF8.GetString(result));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Services.BluetoothLock.Tdo
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockInfoAuthTdo
|
||||
{
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
var auth = new LockInfoAuthTdo.Builder
|
||||
{
|
||||
K_seed = null,
|
||||
K_u = null,
|
||||
K_a = null,
|
||||
}.Build();
|
||||
|
||||
Assert.That(auth.K_seed, Is.Not.Null);
|
||||
Assert.That(auth.K_u, Is.Not.Null);
|
||||
Assert.That(auth.K_a, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using Plugin.BLE.Abstractions.Contracts;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.BLE;
|
||||
using DeviceState = Plugin.BLE.Abstractions.DeviceState;
|
||||
using System.Threading;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Services.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockItBaseService
|
||||
{
|
||||
[Test]
|
||||
public void TestConnect_Connected_InvalidArgs()
|
||||
{
|
||||
var device = Rhino.Mocks.MockRepository.GenerateStub<IDevice>();
|
||||
var adapter = Rhino.Mocks.MockRepository.GenerateStub<IAdapter>();
|
||||
var cipher = Rhino.Mocks.MockRepository.GenerateStub<TINK.Model.Device.ICipher>();
|
||||
|
||||
Rhino.Mocks.RhinoMocksExtensions.Stub(device, x => x.State).Return(DeviceState.Disconnected);
|
||||
|
||||
var exception = Assert.Throws<AggregateException>(
|
||||
() => { 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<BluetoothDisconnectedException>());
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConnect_Connected()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var cipher = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
var auth = Substitute.For<ICharacteristic>();
|
||||
var lockControl = Substitute.For<IService>();
|
||||
|
||||
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(DeviceState.Connected);
|
||||
device.GetServiceAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>()).Returns(Task.FromResult(lockControl));
|
||||
lockControl.GetCharacteristicAsync(Arg.Any<Guid>()).Returns(Task.FromResult(auth));
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true)); // Write COPRI seed to lock
|
||||
auth.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[8])); // Read lock seed
|
||||
cipher.Decrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[3]);
|
||||
cipher.Encrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[16]);
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true)); // Write COPRI seed to lock
|
||||
|
||||
device.Name.Returns("Origin");
|
||||
|
||||
Assert.AreEqual(
|
||||
"Origin",
|
||||
LockItEventBased.Authenticate(device, authTdo, adapter, cipher).Result.Name,
|
||||
"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 = Rhino.Mocks.MockRepository.GenerateStub<IDevice>();
|
||||
var adapter = Rhino.Mocks.MockRepository.GenerateStub<IAdapter>();
|
||||
var cipher = Rhino.Mocks.MockRepository.GenerateStub<TINK.Model.Device.ICipher>();
|
||||
|
||||
Rhino.Mocks.RhinoMocksExtensions.Stub(device, x => x.State).Return(DeviceState.Disconnected);
|
||||
|
||||
// Use factory to create LockIt-object.
|
||||
var exception = Assert.Throws<AggregateException>(
|
||||
() => { 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<BluetoothDisconnectedException>());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using System;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Service.LockService
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockServiceSimulation
|
||||
{
|
||||
[Test]
|
||||
public void TestUpdateSimulationInstance_Update()
|
||||
{
|
||||
var service = new LocksServiceInReach();
|
||||
|
||||
var bikes = new BikeCollection(new Dictionary<string, TINK.Model.Bike.BC.BikeInfo>()
|
||||
{
|
||||
{ "42", new TINK.Model.Bike.BluetoothLock.BikeInfo("42", 1, new Guid(),new byte[] { 1, 4 }, new byte[] { 3, 4 }, new byte[] { 3, 4 }, DateTime.Now, "a@b", "1" , null /*operator uri*/) },
|
||||
{ "43", new TINK.Model.Bike.BluetoothLock.BikeInfo("43", 3, new Guid(),new byte[] { 4, 4 }, new byte[] { 4, 7 }, new byte[] { 5, 4 }, DateTime.Now, "c@b", "1" , null /*operator uri*/) }
|
||||
}
|
||||
);
|
||||
|
||||
if (service is ILocksServiceFake serviceFake)
|
||||
{
|
||||
serviceFake.UpdateSimulation(bikes);
|
||||
}
|
||||
|
||||
Assert.AreEqual(2, service.GetLocksStateAsync(new List<LockInfoAuthTdo>(), new TimeSpan(0, 0, 3)).Result.Count());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.BLE;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLocksServicesContainerMutable
|
||||
{
|
||||
[Test]
|
||||
public void TestCtorCustomServices()
|
||||
{
|
||||
var ciper = NSubstitute.Substitute.For<ICipher>();
|
||||
var firstService = NSubstitute.Substitute.For<ILocksService>();
|
||||
|
||||
Assert.That(
|
||||
new LocksServicesContainerMutable(
|
||||
firstService.GetType().FullName,
|
||||
new HashSet<ILocksService>() { firstService }
|
||||
).Count,
|
||||
Is.EqualTo(1));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Services;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Services
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestServicesContainerMutable
|
||||
{
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
var container = new ServicesContainerMutable<object>(new List<object> { new A(), new B() }, typeof(B).FullName);
|
||||
Assert.That(container.Active.GetType().FullName, Is.EqualTo("TestTINKLib.Fixtures.ObjectTests.Services.TestServicesContainerMutable+B"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorExceptionDupes()
|
||||
{
|
||||
Assert.That(() => new ServicesContainerMutable<object>(new List<object> { new A(), new B(), new A() }, typeof(B).FullName), Throws.InstanceOf<Exception>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorExceptionActiveNotFound()
|
||||
{
|
||||
Assert.That(() => new ServicesContainerMutable<object>(new List<object> { new A(), new B() }, "C"), Throws.InstanceOf<ArgumentException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSetActive()
|
||||
{
|
||||
var container = new ServicesContainerMutable<object>(new List<object> { new A(), new B() }, typeof(B).FullName);
|
||||
container.SetActive(typeof(A).FullName);
|
||||
Assert.That(container.Active.GetType().FullName, Is.EqualTo("TestTINKLib.Fixtures.ObjectTests.Services.TestServicesContainerMutable+A"));
|
||||
}
|
||||
|
||||
|
||||
private class A
|
||||
{ }
|
||||
|
||||
private class B
|
||||
{ }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using Plugin.BLE.Abstractions;
|
||||
using Plugin.BLE.Abstractions.Contracts;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.BLE;
|
||||
using System.Threading;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Settings.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockIt
|
||||
{
|
||||
[Test]
|
||||
public void TestAuthenticate_InvalidSeed()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var ciper = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
|
||||
var authInfo = new LockInfoAuthTdo.Builder {
|
||||
K_seed = new byte[] { 0 },
|
||||
K_u = new byte[] { 1 }
|
||||
}.Build();
|
||||
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
|
||||
device.Id.Returns(new Guid("00000000-0000-0000-0000-000000000001"));
|
||||
|
||||
Assert.That(() => LockItEventBased.Authenticate(device, authInfo, adapter, ciper), Throws.InstanceOf<AuthKeyException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAuthenticate_InvalidAuthKey()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var ciper = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
|
||||
var authInfo = new LockInfoAuthTdo.Builder
|
||||
{
|
||||
K_seed = new byte[] { (byte)'t', (byte)'q', (byte)'2', (byte)'n', (byte)'c', (byte)'A', (byte)'I', (byte)'v', (byte)'M', (byte)'t', (byte)'h', (byte)'g', (byte)'x', (byte)'a', (byte)'z', (byte)'B' },
|
||||
K_u = new byte[] { }
|
||||
}.Build();
|
||||
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("00000000-0000-0000-0000-000000000001"));
|
||||
|
||||
Assert.That(async () => { await LockItEventBased.Authenticate(device, authInfo, adapter, ciper); }, Throws.InstanceOf<AuthKeyException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAuthenticate_Invalidated()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var cipher = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
var auth = Substitute.For<ICharacteristic>();
|
||||
var lockControl = Substitute.For<IService>();
|
||||
var state = Substitute.For<ICharacteristic>();
|
||||
var activateLock = Substitute.For<ICharacteristic>();
|
||||
|
||||
var authInfo = new LockInfoAuthTdo.Builder
|
||||
{
|
||||
K_seed = new byte[] { (byte)'z', (byte)'D', (byte)'G', (byte)'x', (byte)'q', (byte)'M', (byte)'f', (byte)'A', (byte)'F', (byte)'q', (byte)'g', (byte)'N', (byte)'V', (byte)'r', (byte)'N', (byte)'Y' },
|
||||
K_u = new byte[] { 1 }
|
||||
}.Build();
|
||||
|
||||
// Calls related to Authenticate functionality.
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("0000f00d-1212-efde-1523-785fef13d123"));
|
||||
device.GetServiceAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>()).Returns(Task.FromResult(lockControl));
|
||||
lockControl.GetCharacteristicAsync(new Guid("0000baab-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(auth));
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true));
|
||||
auth.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[8]));
|
||||
cipher.Decrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[3]);
|
||||
cipher.Encrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[16]);
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(true);
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("00000000-0000-0000-0000-000000000001"));
|
||||
|
||||
// Call authenticate to invalidate seed
|
||||
var lockIt = LockItEventBased.Authenticate(device, authInfo, adapter, cipher).Result;
|
||||
|
||||
// Authenticate again to
|
||||
var execption = Assert.Throws<AggregateException>(() => { var dummy = LockItEventBased.Authenticate(device, authInfo, adapter, cipher).Result; });
|
||||
|
||||
Assert.That(
|
||||
execption.InnerExceptions[0].Message,
|
||||
Does.Contain ("Seed 122,68,71,120,113,77,102,65,70,113,103,78,86,114,78,89 was already used."));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAuthenticate_GetAuthCharacteristicThrowsException()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var cipher = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
var auth = Substitute.For<ICharacteristic>();
|
||||
var lockControl = Substitute.For<IService>();
|
||||
var state = Substitute.For<ICharacteristic>();
|
||||
var activateLock = Substitute.For<ICharacteristic>();
|
||||
|
||||
var authInfo = new LockInfoAuthTdo.Builder
|
||||
{
|
||||
K_seed = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||
K_u = new byte[] { 1 }
|
||||
}.Build();
|
||||
|
||||
// Calls related to Authenticate functionality.
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("0000f00d-1212-efde-1523-785fef13d123"));
|
||||
device.GetServiceAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>()).Returns(Task.FromResult(lockControl));
|
||||
lockControl.GetCharacteristicAsync(new Guid("0000baab-1212-efde-1523-785fef13d123")).Returns(Task.FromResult((ICharacteristic)null));
|
||||
|
||||
// Authenticate again to
|
||||
Assert.That(() => LockItEventBased.Authenticate(device, authInfo, adapter, cipher), Throws.InstanceOf<CoundntGetCharacteristicException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestAuthenticate_GetLockState_Closed()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var cipher = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
var auth = Substitute.For<ICharacteristic>();
|
||||
var lockControl = Substitute.For<IService>();
|
||||
var state = Substitute.For<ICharacteristic>();
|
||||
|
||||
var authInfo = new LockInfoAuthTdo.Builder
|
||||
{
|
||||
K_seed = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
||||
K_u = new byte[] { 1 }
|
||||
}.Build();
|
||||
|
||||
// Calls related to Authenticate functionality.
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("0000f00d-1212-efde-1523-785fef13d123"));
|
||||
device.GetServiceAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>()).Returns(Task.FromResult(lockControl));
|
||||
lockControl.GetCharacteristicAsync(new Guid("0000baab-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(auth));
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true));
|
||||
auth.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[8]));
|
||||
cipher.Decrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[3]);
|
||||
cipher.Encrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[16]);
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(true);
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("00000000-0000-0000-0000-000000000001"));
|
||||
// Calls related to get lock state.
|
||||
|
||||
// Call authenticate to invalidate seed
|
||||
lockControl.GetCharacteristicAsync(new Guid("0000baaa-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(state));
|
||||
state.ReadAsync(Arg.Any<CancellationToken>()).Returns(new byte[] { 1 });
|
||||
|
||||
var lockIt = LockItEventBased.Authenticate(device, authInfo, adapter, cipher).Result;
|
||||
|
||||
Assert.That((await lockIt.GetLockStateAsync()).State, Is.EqualTo(LockitLockingState.Closed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAuthenticate_GetLockState_GetStateCharacteristicThrowsException()
|
||||
{
|
||||
var device = Substitute.For<IDevice>();
|
||||
var adapter = Substitute.For<IAdapter>();
|
||||
var cipher = Substitute.For<TINK.Model.Device.ICipher>();
|
||||
var auth = Substitute.For<ICharacteristic>();
|
||||
var lockControl = Substitute.For<IService>();
|
||||
|
||||
var authInfo = new LockInfoAuthTdo.Builder
|
||||
{
|
||||
K_seed = new byte[] { (byte)'y', (byte)'D', (byte)'G', (byte)'x', (byte)'q', (byte)'M', (byte)'f', (byte)'A', (byte)'F', (byte)'q', (byte)'g', (byte)'N', (byte)'V', (byte)'r', (byte)'N', (byte)'Y' },
|
||||
K_u = new byte[] { 1 }
|
||||
}.Build();
|
||||
|
||||
// Calls related to Authenticate functionality.
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("0000f00d-1212-efde-1523-785fef13d123"));
|
||||
device.GetServiceAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>()).Returns(Task.FromResult(lockControl));
|
||||
lockControl.GetCharacteristicAsync(new Guid("0000baab-1212-efde-1523-785fef13d123")).Returns(Task.FromResult(auth));
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(Task.FromResult(true));
|
||||
auth.ReadAsync(Arg.Any<CancellationToken>()).Returns(Task.FromResult(new byte[8]));
|
||||
cipher.Decrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[3]);
|
||||
cipher.Encrypt(Arg.Any<byte[]>(), Arg.Any<byte[]>()).Returns(new byte[16]);
|
||||
auth.WriteAsync(Arg.Any<byte[]>()).Returns(true);
|
||||
device.State.Returns(DeviceState.Connected);
|
||||
device.Id.Returns(new Guid("00000000-0000-0000-0000-000000000001"));
|
||||
|
||||
// Calls related to get lock state.
|
||||
lockControl.GetCharacteristicAsync(new Guid("0000baaa-1212-efde-1523-785fef13d123")).Returns(Task.FromResult((ICharacteristic)null));
|
||||
|
||||
var lockIt = LockItEventBased.Authenticate(device, authInfo, adapter, cipher).Result;
|
||||
|
||||
Assert.That(async () => (await lockIt.GetLockStateAsync()).State, Throws.InstanceOf<CoundntGetCharacteristicException>());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model;
|
||||
using TINK.ViewModel.Settings;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Settings
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestGroupFilterSettings
|
||||
{
|
||||
[Test]
|
||||
public void TestDoFilter()
|
||||
{
|
||||
var l_oFilter = new GroupFilterSettings(new Dictionary<string, FilterState> { { "Konrad", FilterState.Off }, { "TINK", FilterState.On }, { "FutureBikeType", FilterState.On} });
|
||||
|
||||
var l_oResult = l_oFilter.DoFilter(new List<string> { "Konrad", "TINK" });
|
||||
|
||||
Assert.AreEqual(1, l_oResult.ToList().Count);
|
||||
Assert.AreEqual("TINK", l_oResult.ToList()[0]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Settings;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Settings
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestPollingParameters
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
Assert.IsTrue(new PollingParameters(new TimeSpan(0, 0, 11), true).IsActivated);
|
||||
Assert.AreEqual(11, (new PollingParameters(new TimeSpan(0, 0, 11), true).Periode.TotalSeconds));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEquals()
|
||||
{
|
||||
Assert.IsTrue((new PollingParameters(new TimeSpan(0, 0, 11), true)) == (new PollingParameters(new TimeSpan(0, 0, 11), true)));
|
||||
Assert.IsFalse((new PollingParameters(new TimeSpan(0, 0, 11), false)) == (new PollingParameters(new TimeSpan(0, 0, 11), true)));
|
||||
Assert.IsFalse((new PollingParameters(new TimeSpan(0, 0, 12), true)) == (new PollingParameters(new TimeSpan(0, 0, 11), true)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUnequals()
|
||||
{
|
||||
Assert.IsFalse((new PollingParameters(new TimeSpan(0, 0, 11), true)) != (new PollingParameters(new TimeSpan(0, 0, 11), true)));
|
||||
Assert.IsTrue((new PollingParameters(new TimeSpan(0, 0, 11), false)) != (new PollingParameters(new TimeSpan(0, 0, 11), true)));
|
||||
Assert.IsTrue((new PollingParameters(new TimeSpan(0, 0, 12), true)) != (new PollingParameters(new TimeSpan(0, 0, 11), true)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestToString()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"Polling is on=True, polling interval=11[sec].",
|
||||
(new PollingParameters(new TimeSpan(0, 0, 11), true).ToString()));
|
||||
}
|
||||
}
|
||||
}
|
42
TestTINKLib/Fixtures/ObjectTests/Settings/TestSettings.cs
Normal file
42
TestTINKLib/Fixtures/ObjectTests/Settings/TestSettings.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using NUnit.Framework;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using TINK.Settings;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Settings
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSettings
|
||||
{
|
||||
[Test]
|
||||
public void TestConstructDefaults()
|
||||
{
|
||||
var settings = new TINK.Model.Settings.Settings();
|
||||
|
||||
Assert.AreEqual(LogEventLevel.Error, settings.MinimumLogEventLevel);
|
||||
|
||||
Assert.AreEqual(GroupFilterHelper.GetSettingsFilterDefaults, settings.GroupFilterSettings);
|
||||
|
||||
Assert.AreEqual(GroupFilterHelper.GetMapPageFilterDefaults, settings.GroupFilterMapPage);
|
||||
|
||||
Assert.AreEqual(new CopriServerUriList().ActiveUri, settings.ActiveUri);
|
||||
|
||||
Assert.AreEqual(PollingParameters.Default, settings.PollingParameters);
|
||||
|
||||
Assert.IsTrue(
|
||||
settings.CenterMapToCurrentLocation,
|
||||
"Center to map for sharee.bike because bt- locks require location info.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorTink()
|
||||
{
|
||||
var settings = new TINK.Model.Settings.Settings(activeUri: new Uri(CopriServerUriList.TINK_LIVE));
|
||||
Assert.IsFalse(
|
||||
settings.CenterMapToCurrentLocation,
|
||||
"Do not center to current location for TINK.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStateBookedInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oBookedInfo = new StateOccupiedInfo(new DateTime(2017, 09, 20, 23, 05, 0), "Heinz@mueller", "17 xxb");
|
||||
|
||||
Assert.AreEqual(
|
||||
new DateTime(2017, 09, 20, 23, 05, 0),
|
||||
l_oBookedInfo.From);
|
||||
|
||||
Assert.AreEqual(
|
||||
"Heinz@mueller",
|
||||
l_oBookedInfo.MailAddress);
|
||||
|
||||
Assert.AreEqual(
|
||||
"17 xxb",
|
||||
l_oBookedInfo.Code);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStateDisposableInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, new StateAvailableInfo().Value);
|
||||
}
|
||||
}
|
||||
}
|
188
TestTINKLib/Fixtures/ObjectTests/State/TestStateInfoMutable.cs
Normal file
188
TestTINKLib/Fixtures/ObjectTests/State/TestStateInfoMutable.cs
Normal file
|
@ -0,0 +1,188 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStateInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oInUseState = new StateInfoMutable(() => new DateTime(2017, 09, 20, 23, 20, 0));
|
||||
|
||||
// Verify initial values of properties.
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oInUseState.Value, "Default state is available");
|
||||
Assert.AreEqual("Disposable", l_oInUseState.ToString());
|
||||
Assert.IsNull(l_oInUseState.RemainingTime);
|
||||
Assert.IsNull(l_oInUseState.From);
|
||||
Assert.IsNull(l_oInUseState.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstructCopy()
|
||||
{
|
||||
// State is available.
|
||||
var l_oSource = MockRepository.GenerateStub<IStateInfo>();
|
||||
l_oSource.Stub(x => x.Value).Return(InUseStateEnum.Disposable);
|
||||
|
||||
var l_oState = new StateInfoMutable(p_oState: l_oSource);
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oState.Value);
|
||||
Assert.IsNull(l_oState.RemainingTime);
|
||||
Assert.IsNull(l_oState.From);
|
||||
Assert.IsNull(l_oState.Code);
|
||||
|
||||
// State is requested.
|
||||
l_oSource = MockRepository.GenerateStub<IStateInfo>();
|
||||
l_oSource.Stub(x => x.Value).Return(InUseStateEnum.Reserved);
|
||||
l_oSource.Stub(x => x.From).Return(new DateTime(2018, 1, 4, 17, 26, 0));
|
||||
l_oSource.Stub(x => x.MailAddress).Return("who@the");
|
||||
l_oSource.Stub(x => x.Code).Return("323");
|
||||
|
||||
l_oState = new StateInfoMutable(() => new DateTime(2018, 1, 4, 17, 30, 1), l_oSource);
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oState.Value);
|
||||
Assert.AreEqual(new TimeSpan(0, 10, 59), l_oState.RemainingTime);
|
||||
Assert.AreEqual(new DateTime(2018, 1, 4, 17, 26, 0), l_oState.From);
|
||||
Assert.AreEqual("who@the", l_oState.MailAddress);
|
||||
Assert.AreEqual("323", l_oState.Code);
|
||||
|
||||
// State is booked.
|
||||
l_oSource = MockRepository.GenerateStub<IStateInfo>();
|
||||
l_oSource.Stub(x => x.Value).Return(InUseStateEnum.Booked);
|
||||
l_oSource.Stub(x => x.From).Return(new DateTime(2018, 1, 4, 17, 00, 0));
|
||||
l_oSource.Stub(x => x.MailAddress).Return("who@the");
|
||||
l_oSource.Stub(x => x.Code).Return("323");
|
||||
|
||||
l_oState = new StateInfoMutable(() => new DateTime(2018, 1, 4, 17, 30, 1), l_oSource);
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oState.Value);
|
||||
Assert.IsNull(l_oState.RemainingTime);
|
||||
Assert.AreEqual(new DateTime(2018, 1, 4, 17, 00, 0), l_oState.From);
|
||||
Assert.AreEqual("who@the", l_oState.MailAddress);
|
||||
Assert.AreEqual("323", l_oState.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoUpdate()
|
||||
{
|
||||
var l_oReservedAt = new DateTime(2017, 09, 20, 22, 01, 00);
|
||||
var l_oDateTimeMock = new DateTimeMocker(new List<DateTime> {
|
||||
l_oReservedAt, // Booking time
|
||||
l_oReservedAt.Add(new TimeSpan(0, 4, 0)), // Reserved for 4 mns
|
||||
l_oReservedAt.Add(new TimeSpan(0, 16, 0)) // Time elapsed since booking 16 mns
|
||||
});
|
||||
|
||||
var l_oStateInfo = new StateInfoMutable(l_oDateTimeMock.GetDateTime);
|
||||
|
||||
// Update state from Copri.
|
||||
l_oStateInfo.Load(
|
||||
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
|
||||
l_oDateTimeMock.GetDateTime(),
|
||||
"heiz@mustermann"); // Owner from Copri.
|
||||
|
||||
// Invoke first update (after simulated 4mns)
|
||||
l_oStateInfo.UpdateOnTimeElapsed();
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateInfo.Value);
|
||||
Assert.AreEqual(11, l_oStateInfo.RemainingTime.Value.Minutes);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oStateInfo.From.Value);
|
||||
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
|
||||
Assert.IsNull(l_oStateInfo.Code);
|
||||
|
||||
// Invoke second update (after simulated 16 mns)
|
||||
l_oStateInfo.UpdateOnTimeElapsed();
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oStateInfo.Value);
|
||||
Assert.IsNull(l_oStateInfo.RemainingTime);
|
||||
Assert.IsNull(l_oStateInfo.From);
|
||||
Assert.IsNull(l_oStateInfo.MailAddress);
|
||||
Assert.IsNull(l_oStateInfo.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpdateFromWebserver()
|
||||
{
|
||||
Func<DateTime> l_oNowMock = () => new DateTime(2017, 09, 21, 23, 40, 0);
|
||||
var l_oStateInfo = new StateInfoMutable(l_oNowMock);
|
||||
|
||||
l_oStateInfo.Load(InUseStateEnum.Booked, new DateTime(2017, 09, 21, 23, 30, 0), "heiz@mustermann", "21");
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oStateInfo.Value);
|
||||
Assert.AreEqual("Booked", l_oStateInfo.ToString());
|
||||
Assert.IsNull(l_oStateInfo.RemainingTime);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 21, 23, 30, 0), l_oStateInfo.From.Value);
|
||||
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
|
||||
Assert.AreEqual("21", l_oStateInfo.Code);
|
||||
|
||||
DateTime FROM = new DateTime(2017, 09, 21, 23, 35, 0);
|
||||
l_oStateInfo.Load(InUseStateEnum.Reserved, FROM, "heiz@mustermann", "22");
|
||||
|
||||
// Verify initial values of properties.
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateInfo.Value);
|
||||
Assert.AreEqual("Reserved", l_oStateInfo.ToString());
|
||||
Assert.AreEqual(new TimeSpan(0, 15, 0).Subtract(l_oNowMock().Subtract(FROM)).Minutes, l_oStateInfo.RemainingTime.Value.Minutes);
|
||||
Assert.AreEqual(FROM, l_oStateInfo.From);
|
||||
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
|
||||
Assert.AreEqual("22", l_oStateInfo.Code);
|
||||
|
||||
l_oStateInfo.Load(InUseStateEnum.Disposable, new DateTime(1970, 1, 1, 0, 0, 0), "heiz@mustermann", "unused");
|
||||
|
||||
// Verify initial values of properties.
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oStateInfo.Value);
|
||||
Assert.AreEqual("Disposable", l_oStateInfo.ToString());
|
||||
Assert.IsNull(l_oStateInfo.RemainingTime);
|
||||
Assert.IsNull(l_oStateInfo.From);
|
||||
Assert.IsNull( l_oStateInfo.MailAddress);
|
||||
Assert.IsNull(l_oStateInfo.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoad()
|
||||
{
|
||||
var l_oState = new StateInfoMutable(
|
||||
() => new DateTime(2018, 01, 03, 21, 14, 0)); // Now
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oState.Value);
|
||||
Assert.IsNull(l_oState.From);
|
||||
Assert.IsNull(l_oState.RemainingTime);
|
||||
Assert.IsNull(l_oState.MailAddress);
|
||||
Assert.IsNull(l_oState.Code);
|
||||
|
||||
// Construct requested state object.
|
||||
var l_oSource = new StateInfo(
|
||||
() => new DateTime(2018, 01, 03, 21, 53, 0),
|
||||
new DateTime(2018, 01, 03, 21, 13, 0), // Requested from
|
||||
"a@b",
|
||||
"123");
|
||||
l_oState.Load(l_oSource);
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oState.Value);
|
||||
Assert.AreEqual(new DateTime(2018, 01, 03, 21, 13, 0), l_oState.From);
|
||||
Assert.AreEqual(14, l_oState.RemainingTime.Value.Minutes);
|
||||
Assert.AreEqual("a@b", l_oState.MailAddress);
|
||||
Assert.AreEqual("123", l_oState.Code);
|
||||
|
||||
|
||||
// Construct booked state object.
|
||||
l_oSource = new StateInfo(new DateTime(2018, 01, 03, 21, 37, 0), "a@b", "123");
|
||||
l_oState.Load(l_oSource);
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oState.Value);
|
||||
Assert.AreEqual(new DateTime(2018, 01, 03, 21, 37, 0), l_oState.From);
|
||||
Assert.IsNull(l_oState.RemainingTime);
|
||||
Assert.AreEqual("a@b", l_oState.MailAddress);
|
||||
Assert.AreEqual("123", l_oState.Code);
|
||||
|
||||
// Construct disposable object
|
||||
l_oSource = new StateInfo();
|
||||
l_oState.Load(l_oSource);
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oState.Value);
|
||||
Assert.IsNull(l_oState.From);
|
||||
Assert.IsNull(l_oState.RemainingTime);
|
||||
Assert.IsNull(l_oState.MailAddress);
|
||||
Assert.IsNull(l_oState.Code);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib.Fixtures.State
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStateInfoSerializeJSON
|
||||
{
|
||||
[Test]
|
||||
public void TestSerializeJSON_Disposable()
|
||||
{
|
||||
string l_strJSONDetected;
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oInUseState = new StateInfoMutable(() => new DateTime(2017, 09, 20, 23, 20, 0));
|
||||
|
||||
// Serialize object and verify json
|
||||
l_strJSONDetected = JsonConvert.SerializeObject(l_oInUseState, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
});
|
||||
|
||||
const string EXPECTED = @"
|
||||
{
|
||||
""StateInfoObject"":
|
||||
{
|
||||
""$type"":""TINK.Model.State.StateAvailableInfo, TINKLib""
|
||||
}
|
||||
}";
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED.Replace("\n", string.Empty).Replace("\r", string.Empty)),
|
||||
TestHelper.PrepareXmlForStringCompare(l_strJSONDetected.Replace("\n", string.Empty).Replace("\r", string.Empty)));
|
||||
}
|
||||
|
||||
{
|
||||
// Deserialize object
|
||||
var l_oInUseStateTarget = JsonConvert.DeserializeObject<StateInfoMutable>(l_strJSONDetected, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
|
||||
// Verify state.
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oInUseStateTarget.Value);
|
||||
Assert.AreEqual("Disposable", l_oInUseStateTarget.ToString());
|
||||
Assert.IsNull(l_oInUseStateTarget.RemainingTime);
|
||||
Assert.IsNull(l_oInUseStateTarget.From);
|
||||
Assert.IsNull(l_oInUseStateTarget.MailAddress);
|
||||
Assert.IsNull(l_oInUseStateTarget.Code);
|
||||
}
|
||||
}
|
||||
[Test]
|
||||
public void TestSerializeJSON_Booked()
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oInUseState = new StateInfoMutable(
|
||||
() => new DateTime(2017, 11, 18, 23, 20, 0) // Mocked time stamp returned when StateInfo- object is crated
|
||||
);
|
||||
|
||||
l_oInUseState.Load(
|
||||
InUseStateEnum.Booked,
|
||||
new DateTime(2017, 11, 18, 23, 19, 0), // Time booked at
|
||||
"heiz@mustermann",
|
||||
"173"); // Code
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oInUseState.Value);
|
||||
Assert.AreEqual("heiz@mustermann", l_oInUseState.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 11, 18, 23, 19, 0), l_oInUseState.From);
|
||||
Assert.AreEqual("173", l_oInUseState.Code);
|
||||
|
||||
// Verify json
|
||||
const string EXPECTED = @"
|
||||
{
|
||||
""StateInfoObject"":
|
||||
{
|
||||
""$type"":""TINK.Model.State.StateOccupiedInfo, TINKLib"",
|
||||
""From"":""2017 - 11 - 18T23: 19:00"",
|
||||
""MailAddress"":""heiz @mustermann"",""Code"":""173""
|
||||
}
|
||||
}";
|
||||
|
||||
var l_oDetected = JsonConvert.SerializeObject(l_oInUseState, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
});
|
||||
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED).Replace("\n", string.Empty).Replace("\r", string.Empty),
|
||||
TestHelper.PrepareXmlForStringCompare(l_oDetected).Replace("\n", string.Empty).Replace("\r", string.Empty));
|
||||
|
||||
// Deserialize object an verify state.
|
||||
var l_oStateTarget = JsonConvert.DeserializeObject<StateInfoMutable>(l_oDetected, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
// Verify state.
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oStateTarget.Value);
|
||||
Assert.AreEqual(new DateTime(2017, 11, 18, 23, 19, 0), l_oInUseState.From);
|
||||
Assert.AreEqual("heiz@mustermann", l_oStateTarget.MailAddress);
|
||||
Assert.AreEqual("173", l_oInUseState.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerializeJSON_Reserved_NoCode()
|
||||
{
|
||||
string l_strJSONDetected;
|
||||
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oInUseState = new StateInfoMutable(() => new DateTime(2017, 09, 21, 23, 20, 0));
|
||||
l_oInUseState.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
new DateTime(2017, 09, 21, 23, 20, 0),
|
||||
"heiz@mustermann");
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oInUseState.Value);
|
||||
Assert.AreEqual("heiz@mustermann", l_oInUseState.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 21, 23, 20, 0), l_oInUseState.From);
|
||||
Assert.AreEqual(new TimeSpan(0, 15, 0), l_oInUseState.RemainingTime);
|
||||
Assert.IsNull(l_oInUseState.Code);
|
||||
|
||||
l_strJSONDetected = JsonConvert.SerializeObject(l_oInUseState, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
});
|
||||
|
||||
// Verify json
|
||||
const string EXPECTED = @"
|
||||
{
|
||||
""StateInfoObject"":
|
||||
{
|
||||
""$type"":""TINK.Model.State.StateRequestedInfo, TINKLib"",
|
||||
""From"":""2017 - 09 - 21T23: 20:00"",
|
||||
""MailAddress"":""heiz @mustermann""
|
||||
}
|
||||
}";
|
||||
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED.Replace("\n", string.Empty).Replace("\r", string.Empty)),
|
||||
TestHelper.PrepareXmlForStringCompare(l_strJSONDetected.Replace("\n", string.Empty).Replace("\r", string.Empty)));
|
||||
}
|
||||
|
||||
{
|
||||
// Deserialize object an verify state.
|
||||
var l_oStateTarget = JsonConvert.DeserializeObject<StateInfoMutable>(l_strJSONDetected, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
// Verify state.
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateTarget.Value);
|
||||
Assert.AreEqual("heiz@mustermann", l_oStateTarget.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 21, 23, 20, 0), l_oStateTarget.From);
|
||||
Assert.IsNull(l_oStateTarget.RemainingTime, "If deserialized date time provider is DateTime.Now. With a from- value of 2017-11- ... there is no more time remaining.");
|
||||
Assert.IsNull(l_oStateTarget.Code);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerializeJSON_Reserved()
|
||||
{
|
||||
string l_strJSONDetected;
|
||||
|
||||
{
|
||||
Func<DateTime> l_oNow = () => new DateTime(2017, 11, 18, 23, 18, 0);
|
||||
// Create object to test.
|
||||
var l_oInUseState = new StateInfoMutable(l_oNow);
|
||||
|
||||
DateTime l_oFrom = new DateTime(2017, 11, 18, 23, 18, 0);
|
||||
l_oInUseState.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
l_oFrom,
|
||||
"z@C",
|
||||
"01815A");
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oInUseState.Value);
|
||||
Assert.AreEqual("z@C", l_oInUseState.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 11, 18, 23, 18, 0), l_oInUseState.From);
|
||||
Assert.AreEqual((new TimeSpan(0, 15, 0)).Subtract(l_oNow().Subtract(l_oFrom)), l_oInUseState.RemainingTime);
|
||||
Assert.AreEqual("01815A", l_oInUseState.Code);
|
||||
|
||||
l_strJSONDetected = JsonConvert.SerializeObject(l_oInUseState, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
NullValueHandling = NullValueHandling.Ignore,
|
||||
});
|
||||
|
||||
// Verify json
|
||||
const string EXPECTED = @"
|
||||
{
|
||||
""StateInfoObject"":
|
||||
{
|
||||
""$type"":""TINK.Model.State.StateRequestedInfo, TINKLib"",
|
||||
""From"":""2017 - 11 - 18T23: 18:00"",
|
||||
""MailAddress"":""z @C"",
|
||||
""Code"":""01815A""
|
||||
}
|
||||
}";
|
||||
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED.Replace("\n", string.Empty).Replace("\r", string.Empty)),
|
||||
TestHelper.PrepareXmlForStringCompare(l_strJSONDetected.Replace("\n", string.Empty).Replace("\r", string.Empty)));
|
||||
}
|
||||
|
||||
{
|
||||
// Deserialize object an verify state.
|
||||
var l_oStateTarget = JsonConvert.DeserializeObject<StateInfoMutable>(l_strJSONDetected, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
|
||||
// Verify state.
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateTarget.Value);
|
||||
Assert.AreEqual("z@C", l_oStateTarget.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 11, 18, 23, 18, 0), l_oStateTarget.From);
|
||||
Assert.IsNull(l_oStateTarget.RemainingTime, "If deserialized date time provider is DateTime.Now. With a from- value of 2017-11- ... there is no more time remaining.");
|
||||
Assert.AreEqual("01815A", l_oStateTarget.Code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStateRequestedInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct_FromApp()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
InUseStateEnum.Reserved,
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).Value);
|
||||
|
||||
Assert.AreEqual(
|
||||
"a@b",
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).MailAddress);
|
||||
|
||||
Assert.IsNull(
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).Code);
|
||||
|
||||
Assert.AreEqual(
|
||||
new DateTime(2017, 09, 20, 12, 0, 0),
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).From);
|
||||
|
||||
Assert.IsTrue(
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).GetIsStillReserved(out TimeSpan? l_oRemainigTime));
|
||||
|
||||
Assert.AreEqual(
|
||||
14,
|
||||
l_oRemainigTime.Value.Minutes);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_FromWebserver()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
InUseStateEnum.Reserved,
|
||||
new StateRequestedInfo(() => new DateTime(2017,09, 20), new DateTime(2017, 09, 19), "a@b", "372").Value);
|
||||
|
||||
Assert.AreEqual(
|
||||
"a@b",
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").MailAddress);
|
||||
|
||||
Assert.AreEqual(
|
||||
"372",
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").Code);
|
||||
|
||||
Assert.AreEqual(
|
||||
new DateTime(2017,09, 19),
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").From);
|
||||
|
||||
Assert.IsTrue(
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 12, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", "372").GetIsStillReserved(out TimeSpan? l_oRemainigTime));
|
||||
|
||||
Assert.AreEqual(
|
||||
3,
|
||||
l_oRemainigTime.Value.Minutes);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestTryUpdateOnTimeElapsed()
|
||||
{
|
||||
var l_oReservedAt = new DateTime(2017, 09, 20, 22, 01, 00);
|
||||
var l_oDateTimeMock = new DateTimeMocker( new List<DateTime> {
|
||||
l_oReservedAt.Add(new TimeSpan(0, 4, 0)), // Reserved for 4 mns
|
||||
l_oReservedAt.Add(new TimeSpan(0, 16, 0)) // Time elapsed since booking 16 mns
|
||||
});
|
||||
|
||||
var l_oReservedInfo = new StateRequestedInfo(l_oDateTimeMock.GetDateTime, l_oReservedAt, "a@b", null);
|
||||
Assert.AreEqual("a@b", l_oReservedInfo.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
|
||||
|
||||
// Invoke first update (after simulated 4mns)
|
||||
Assert.IsTrue(l_oReservedInfo.GetIsStillReserved(out TimeSpan? l_oRemainigTime));
|
||||
Assert.AreEqual(11, l_oRemainigTime.Value.Minutes);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
|
||||
|
||||
// Invoke second update (after simulated 16 mns)
|
||||
Assert.IsFalse(l_oReservedInfo.GetIsStillReserved(out l_oRemainigTime));
|
||||
Assert.IsNull(l_oRemainigTime);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.State;
|
||||
|
||||
|
||||
namespace TestTINKLib.Fixtures.State
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStateReInquestedfoSerializeJSON
|
||||
{
|
||||
[Test]
|
||||
public void TestSerializeJSON()
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oReservedInfo = new StateRequestedInfo(
|
||||
() => new DateTime(2017, 09, 20),
|
||||
new DateTime(2017, 09, 19),
|
||||
"a@b",
|
||||
"372");
|
||||
|
||||
// Serialize object
|
||||
// Serialize object and verify.
|
||||
var l_oDetected = JsonConvert.SerializeObject(l_oReservedInfo);
|
||||
// Verify xml
|
||||
const string EXPECTED = @"{""From"":""2017 - 09 - 19T00: 00:00"",""MailAddress"":""a @b"",""Code"":""372""}";
|
||||
Assert.AreEqual(
|
||||
TestHelper.PrepareXmlForStringCompare(EXPECTED),
|
||||
TestHelper.PrepareXmlForStringCompare(l_oDetected));
|
||||
|
||||
// Deserialize object.
|
||||
var l_oInfoTarge = JsonConvert.DeserializeObject<StateRequestedInfo>(l_oDetected);
|
||||
|
||||
// Verify state.
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oInfoTarge.Value);
|
||||
Assert.AreEqual("a@b", l_oInfoTarge.MailAddress);
|
||||
Assert.AreEqual("372", l_oInfoTarge.Code);
|
||||
Assert.AreEqual(new DateTime(2017, 9, 19, 0, 0, 0), l_oInfoTarge.From);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
26
TestTINKLib/Fixtures/ObjectTests/Station/TestNullStation.cs
Normal file
26
TestTINKLib/Fixtures/ObjectTests/Station/TestNullStation.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using NUnit.Framework;
|
||||
using System.Linq;
|
||||
using TINK.Model.Station;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Station
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestNullStation
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oNull = new NullStation();
|
||||
|
||||
// Was -1 before swiching type of id from int to string when switching from COPRI version v4.0 to v4.1
|
||||
Assert.That(
|
||||
l_oNull.Id,
|
||||
Is.Null);
|
||||
|
||||
Assert.AreEqual(0, l_oNull.Group.ToList().Count);
|
||||
Assert.AreEqual(string.Empty, l_oNull.StationName);
|
||||
Assert.IsNaN(l_oNull.Position.Latitude);
|
||||
Assert.IsNaN(l_oNull.Position.Longitude);
|
||||
}
|
||||
}
|
||||
}
|
42
TestTINKLib/Fixtures/ObjectTests/Station/TestStation.cs
Normal file
42
TestTINKLib/Fixtures/ObjectTests/Station/TestStation.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.Station;
|
||||
|
||||
|
||||
namespace TestTINKLib.Fixtures.Station
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestStation
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oStation = new TINK.Model.Station.Station("7", new HashSet<string>(new List<string> { "TINK" }).ToList(), new Position(1,2), "Hallo");
|
||||
Assert.AreEqual("7", l_oStation.Id);
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oStation.Group));
|
||||
Assert.AreEqual(1, l_oStation.Position.Latitude);
|
||||
Assert.AreEqual(2, l_oStation.Position.Longitude);
|
||||
Assert.AreEqual("Hallo", l_oStation.StationName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_InvalidStationName()
|
||||
{
|
||||
var l_oStation = new TINK.Model.Station.Station("7", new HashSet<string>(new List<string> { "TINK" }).ToList(), new Position(1, 2), null);
|
||||
Assert.AreEqual("7", l_oStation.Id);
|
||||
Assert.AreEqual("TINK", string.Join(",", l_oStation.Group));
|
||||
Assert.AreEqual(1, l_oStation.Position.Latitude);
|
||||
Assert.AreEqual(2, l_oStation.Position.Longitude);
|
||||
Assert.AreEqual("", l_oStation.StationName);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_InvalidStationGroup()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new TINK.Model.Station.Station("7", null, new Position(1, 2), "Hallo"));
|
||||
}
|
||||
}
|
||||
}
|
26
TestTINKLib/Fixtures/ObjectTests/TestFilterCollection.cs
Normal file
26
TestTINKLib/Fixtures/ObjectTests/TestFilterCollection.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model;
|
||||
using TINK.ViewModel.Map;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestFilterCollection
|
||||
{
|
||||
[Test]
|
||||
public void TestGetGroup()
|
||||
{
|
||||
var l_oFilterColl = new GroupFilterMapPage( new Dictionary<string, FilterState>
|
||||
{
|
||||
{ "TINK", FilterState.On },
|
||||
{ "Konrad", FilterState.On }
|
||||
});
|
||||
|
||||
var l_oFilterGroup = l_oFilterColl.GetGroup();
|
||||
Assert.AreEqual(2, l_oFilterGroup.Count);
|
||||
Assert.AreEqual("TINK", l_oFilterGroup[0]);
|
||||
Assert.AreEqual("Konrad", l_oFilterGroup[1]);
|
||||
}
|
||||
}
|
||||
}
|
124
TestTINKLib/Fixtures/ObjectTests/TestFilterCollectionStore.cs
Normal file
124
TestTINKLib/Fixtures/ObjectTests/TestFilterCollectionStore.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Settings;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestFilterCollectionStore
|
||||
{
|
||||
[Test]
|
||||
public void TestSerialize_Null()
|
||||
{
|
||||
var l_oSettings = new Dictionary<string, string>().SetGroupFilterSettings(null);
|
||||
var l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.IsNull(l_oFilterColl);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerialize_Invalid()
|
||||
{
|
||||
var l_oSettings = new Dictionary<string, string>().SetGroupFilterSettings(new Dictionary<string, FilterState>());
|
||||
var l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.IsNull(l_oFilterColl);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerializeLegacy()
|
||||
{
|
||||
var l_oSettings = new Dictionary<string, string>().SetGroupFilterSettings(
|
||||
new Dictionary<string, FilterState>
|
||||
{
|
||||
{ "TINK.Copri", FilterState.On },
|
||||
{ "TINK.SMS", FilterState.Off},
|
||||
{ "Konrad", FilterState.On }
|
||||
});
|
||||
|
||||
var l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.AreEqual(2, l_oFilterColl.Count);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["Konrad"]);
|
||||
|
||||
l_oSettings = new Dictionary<string, string>().SetGroupFilterSettings(
|
||||
new Dictionary<string, FilterState>
|
||||
{
|
||||
{ "TINK.Copri", FilterState.Off },
|
||||
{ "TINK.SMS", FilterState.On},
|
||||
{ "Konrad", FilterState.On }
|
||||
});
|
||||
|
||||
l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.AreEqual(2, l_oFilterColl.Count);
|
||||
Assert.AreEqual(FilterState.Off, l_oFilterColl["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["Konrad"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerializeInvalid()
|
||||
{
|
||||
var l_oSettings = new Dictionary<string, string>()
|
||||
.SetGroupFilterSettings(
|
||||
new Dictionary<string, FilterState>
|
||||
{
|
||||
{ "TINK.SMS", FilterState.Off},
|
||||
{ "Konrad", FilterState.On }
|
||||
});
|
||||
|
||||
var l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.AreEqual(2, l_oFilterColl.Count);
|
||||
Assert.AreEqual(FilterState.Off, l_oFilterColl["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["Konrad"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSerializeRoundtrip()
|
||||
{
|
||||
var l_oSettings = new Dictionary<string, string>()
|
||||
.SetGroupFilterSettings(
|
||||
new Dictionary<string, FilterState>
|
||||
{
|
||||
{ "TINK", FilterState.On },
|
||||
{ "Konrad", FilterState.On }
|
||||
});
|
||||
|
||||
var l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.AreEqual(2, l_oFilterColl.Count);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["Konrad"]);
|
||||
|
||||
l_oSettings = new Dictionary<string, string>().SetGroupFilterSettings(
|
||||
new Dictionary<string, FilterState>
|
||||
{
|
||||
{ "TINK", FilterState.Off },
|
||||
{ "Konrad", FilterState.On }
|
||||
});
|
||||
|
||||
l_oFilterColl = JsonSettingsDictionary.GetGoupFilterSettings(l_oSettings);
|
||||
|
||||
Assert.AreEqual(2, l_oFilterColl.Count);
|
||||
Assert.AreEqual(FilterState.Off, l_oFilterColl["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oFilterColl["Konrad"]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_ToString_Emtpy()
|
||||
{
|
||||
Assert.AreEqual("{}", FilterCollectionStore.ToString(new Dictionary<string, FilterState>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_ToString()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"{(Test1= Off), (Test2= On)}",
|
||||
FilterCollectionStore.ToString(new Dictionary<string, FilterState> { { "Test1", FilterState.Off}, {"Test2", FilterState.On}}));
|
||||
}
|
||||
}
|
||||
}
|
126
TestTINKLib/Fixtures/ObjectTests/TestJsonSettingsDictionary.cs
Normal file
126
TestTINKLib/Fixtures/ObjectTests/TestJsonSettingsDictionary.cs
Normal file
|
@ -0,0 +1,126 @@
|
|||
using NUnit.Framework;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.Settings;
|
||||
using TINK.Settings;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestJsonSettingsDictionary
|
||||
{
|
||||
/// <summary> Verifies that empty log fiel leads to expected default value and doesn not throw exceptions.</summary>
|
||||
[Test]
|
||||
public void TestGetCopriHostUri_NoFile()
|
||||
{
|
||||
Assert.IsNull(JsonSettingsDictionary.GetCopriHostUri(new Dictionary<string, string>()));
|
||||
}
|
||||
|
||||
/// <summary> Verifies that empty log file leads to expected default value and doesn not throw exceptions.</summary>
|
||||
[Test]
|
||||
public void TestGetPolling()
|
||||
{
|
||||
// Serialize parameters.
|
||||
var l_oDict = new Dictionary<string, string>()
|
||||
.SetPollingParameters(new PollingParameters(new TimeSpan(0, 0, 0, 15, 0), false));
|
||||
|
||||
// Deserialize parameters.
|
||||
Assert.AreEqual(
|
||||
new PollingParameters(new TimeSpan(0, 0, 0, 15, 0), false),
|
||||
l_oDict.GetPollingParameters());
|
||||
}
|
||||
|
||||
/// <summary> Verifies that empty log fiel leads to expected default value and doesn not throw exceptions.</summary>
|
||||
[Test]
|
||||
public void TestGetPolling_NoFile()
|
||||
{
|
||||
Assert.IsNull(JsonSettingsDictionary.GetPollingParameters(new Dictionary<string, string>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetGetCopriHostUri()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string>()
|
||||
.SetCopriHostUri("http://1.2.3.4");
|
||||
Assert.AreEqual(
|
||||
new Uri("http://1.2.3.4"),
|
||||
JsonSettingsDictionary.GetCopriHostUri(l_oDict));
|
||||
}
|
||||
|
||||
/// <summary> Verifies that empty log fiel leads to expected default value and doesn not throw exceptions.</summary>
|
||||
[Test]
|
||||
public void TestGetLoggingLevel()
|
||||
{
|
||||
var l_oDictionary = new Dictionary<string, string>()
|
||||
.SetMinimumLoggingLevel(0); // Verbose = 0
|
||||
Assert.AreEqual(
|
||||
LogEventLevel.Verbose,
|
||||
JsonSettingsDictionary.GetMinimumLoggingLevel(l_oDictionary)); // LogEventLevel.Error = 4
|
||||
}
|
||||
|
||||
/// <summary> Verifies that empty log fiel leads to expected default value and doesn not throw exceptions.</summary>
|
||||
[Test]
|
||||
public void TestGetLoggingLevel_NoFile()
|
||||
{
|
||||
Assert.IsNull(JsonSettingsDictionary.GetMinimumLoggingLevel(new Dictionary<string, string>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetAppVersion_FirstInstall()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string> ();
|
||||
Assert.IsNull(JsonSettingsDictionary.GetAppVersion(l_oDict));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetAppVersion_LegacyTo115()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string> { { "AppVersion", "7.2.3.9" } };
|
||||
Assert.AreEqual(new Version(7,2,3,9), JsonSettingsDictionary.GetAppVersion(l_oDict));
|
||||
|
||||
l_oDict = new Dictionary<string, string> { { "AppVersion", "7.2.3" } };
|
||||
Assert.AreEqual(new Version(7, 2, 3), JsonSettingsDictionary.GetAppVersion(l_oDict));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetAppVersion_Json()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string> { { "AppVersion", "\"3.1.2.117\"" } };
|
||||
Assert.AreEqual(new Version(3, 1, 2, 117), JsonSettingsDictionary.GetAppVersion(l_oDict));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSetAppVersion_Json()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string>()
|
||||
.SetAppVersion(new Version(47, 12, 3));
|
||||
Assert.AreEqual(new Version(47, 12, 3), JsonSettingsDictionary.GetAppVersion(l_oDict));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetShowWhatsNew_FirstInstall()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string>();
|
||||
Assert.IsNull(JsonSettingsDictionary.GetWhatsNew(l_oDict));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetShowWhatsNew_Json()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string> { { "ShowWhatsNew", "\"3.1.2.117\"" } };
|
||||
Assert.AreEqual(new Version(3, 1, 2, 117), JsonSettingsDictionary.GetWhatsNew(l_oDict));
|
||||
|
||||
l_oDict = new Dictionary<string, string> { { "ShowWhatsNew", "\"3.1.2\"" } };
|
||||
Assert.AreEqual(new Version(3, 1, 2), JsonSettingsDictionary.GetWhatsNew(l_oDict));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSetShowWhats_Json()
|
||||
{
|
||||
var l_oDict = new Dictionary<string, string>()
|
||||
.SetWhatsNew(new Version(47, 12, 3));
|
||||
Assert.AreEqual(new Version(47, 12, 3), JsonSettingsDictionary.GetWhatsNew(l_oDict));
|
||||
}
|
||||
}
|
||||
}
|
46
TestTINKLib/Fixtures/ObjectTests/TestPollingTaskManager.cs
Normal file
46
TestTINKLib/Fixtures/ObjectTests/TestPollingTaskManager.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
using NUnit.Framework;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.ViewModel;
|
||||
using TINK.Settings;
|
||||
|
||||
namespace UITest.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestPollingTaskManager
|
||||
{
|
||||
[Test]
|
||||
public async Task TestStopUpdatePeriodiallyRepeated()
|
||||
{
|
||||
var l_oManger = new PollingUpdateTaskManager(() => "Test", () => Task.Delay(1000));
|
||||
|
||||
await l_oManger.StartUpdateAyncPeridically(new PollingParameters(new System.TimeSpan(0, 0, 2), true));
|
||||
|
||||
l_oManger.StopUpdatePeridically().Wait();
|
||||
|
||||
// Should not lead to dead lock.
|
||||
l_oManger.StopUpdatePeridically().Wait();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestStartUpdatePeriodiallyRepeated()
|
||||
{
|
||||
var l_oManger = new PollingUpdateTaskManager(() => "Test", () => Task.Delay(1000));
|
||||
|
||||
await l_oManger.StartUpdateAyncPeridically(new PollingParameters(new System.TimeSpan(0, 0, 2), true));
|
||||
|
||||
// Should not lead to dead lock.
|
||||
await l_oManger.StartUpdateAyncPeridically(new PollingParameters(new System.TimeSpan(0, 0, 2), true));
|
||||
|
||||
l_oManger.StopUpdatePeridically().Wait();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestStopUpdatePeriodiallyNoStart()
|
||||
{
|
||||
var l_oManger = new PollingUpdateTaskManager(() => "Test", () => Task.Delay(1000));
|
||||
|
||||
// Should not lead to dead lock.
|
||||
await l_oManger.StartUpdateAyncPeridically(new PollingParameters(new System.TimeSpan(0, 0, 2), true));
|
||||
}
|
||||
}
|
||||
}
|
21
TestTINKLib/Fixtures/ObjectTests/TestPollingUpdateTask.cs
Normal file
21
TestTINKLib/Fixtures/ObjectTests/TestPollingUpdateTask.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using NUnit.Framework;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.ViewModel;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestPollingUpdateTask
|
||||
{
|
||||
[Test]
|
||||
public void TestTerminateRepeated()
|
||||
{
|
||||
var l_oTaks = new PollingUpdateTask(() => "Test", async () => await Task.Delay(1000), new System.TimeSpan(0, 0, 2));
|
||||
|
||||
l_oTaks.Terminate().Wait();
|
||||
|
||||
// Verify that calling terminate twice does not lead to hang of call.
|
||||
l_oTaks.Terminate().Wait();
|
||||
}
|
||||
}
|
||||
}
|
76
TestTINKLib/Fixtures/ObjectTests/TestWhatsNew.cs
Normal file
76
TestTINKLib/Fixtures/ObjectTests/TestWhatsNew.cs
Normal file
|
@ -0,0 +1,76 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestWhatsNew
|
||||
{
|
||||
[Test]
|
||||
public void TestIsShowRequired_CleanInstall()
|
||||
{
|
||||
Assert.IsFalse(new WhatsNew(
|
||||
new Version(2, 4), /* Current version */
|
||||
null, // last version
|
||||
null /* Whats new was never shown */ ).IsShowRequired);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsShowRequired_Update_VersionWhichSupporsWhatsNew()
|
||||
{
|
||||
Assert.IsTrue(
|
||||
new WhatsNew(
|
||||
new Version(2, 5), /* Current version */
|
||||
new Version(2, 3), /* last version */
|
||||
new Version(2, 1) /* Version when whats new was shown */ ).IsShowRequired,
|
||||
"If whats new was last shonw for version 2.1 and current version is 2.5 info must be shown");
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestIsShowRequired_Update_VersionWithoutWhatsNew()
|
||||
{
|
||||
Assert.IsTrue(
|
||||
new WhatsNew(
|
||||
new Version(2, 5), /* Current version */
|
||||
new Version(2, 3), /* last version */
|
||||
null /* Whats new was never shown */ ).IsShowRequired,
|
||||
"If whats new was never shown but last version was 2.3 (not clean install) info must be shown");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsShowRequired_False()
|
||||
{
|
||||
Assert.IsFalse(
|
||||
new WhatsNew(new Version(2, 5), new Version(2, 5), new Version(2, 5)).IsShowRequired,
|
||||
"Whats new must never be presented twice.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestIsShowRequired_False_Errors()
|
||||
{
|
||||
Assert.IsFalse(new WhatsNew(null, new Version(2,6), new Version(2, 5)).IsShowRequired);
|
||||
Assert.IsFalse(new WhatsNew(new Version(2, 6), null, new Version(2, 5)).IsShowRequired);
|
||||
Assert.IsFalse(new WhatsNew(null, null, new Version(2, 5)).IsShowRequired);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestWhatsNewText_MajorUpdate()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"<p><b>3.0.0.115</b><br/>Benutzeroberfläche verbessert.\r\n\r\n" +
|
||||
"</p><p><b>3.0.120</b><br/>Verbesserung: Keine Fehler mehr beim schnellen Tippen.\r\nOfflineanzeige Stationen/ Räderinfo.\r\n\r\n</p>",
|
||||
new WhatsNew(new Version(3, 0, 120), new Version(3, 0, 0, 114), new Version(3, 0, 0, 114)).WhatsNewText,
|
||||
"Current version is 30.0.120, last whats new was shown in version 3.0.0.114: Two changes to be notified about.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestWhatsNewText_MinorUpdate()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
"<p><b>3.0.120</b><br/>Verbesserung: Keine Fehler mehr beim schnellen Tippen.\r\nOfflineanzeige Stationen/ Räderinfo.\r\n\r\n</p>",
|
||||
new WhatsNew(new Version(3, 0, 120), new Version(3, 0, 0, 115), new Version(3, 0, 0, 115)).WhatsNewText);
|
||||
}
|
||||
}
|
||||
}
|
42
TestTINKLib/Fixtures/ObjectTests/User/Account/TestAccount.cs
Normal file
42
TestTINKLib/Fixtures/ObjectTests/User/Account/TestAccount.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UITest.Fixtures.ObjectTests.User.Account
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestAccount
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oAccount = new TINK.Model.User.Account.Account("a@b", "112", "3330", new List<string> { "Honkey", "Tonkey" }, TINK.Model.User.Account.Permissions.None);
|
||||
|
||||
Assert.AreEqual("a@b", l_oAccount.Mail);
|
||||
Assert.AreEqual("112", l_oAccount.Pwd);
|
||||
Assert.AreEqual("3330", l_oAccount.SessionCookie);
|
||||
Assert.AreEqual("Honkey,Tonkey", String.Join(",", l_oAccount.Group));
|
||||
Assert.AreEqual(TINK.Model.User.Account.Permissions.None, l_oAccount.DebugLevel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_Copy()
|
||||
{
|
||||
var l_oAccount = new TINK.Model.User.Account.Account(new TINK.Model.User.Account.Account("a@b", "112", "3330", new List<string> { "Honkey", "Tonkey" },TINK.Model.User.Account.Permissions.None));
|
||||
|
||||
Assert.AreEqual("a@b", l_oAccount.Mail);
|
||||
Assert.AreEqual("112", l_oAccount.Pwd);
|
||||
Assert.AreEqual("3330", l_oAccount.SessionCookie);
|
||||
Assert.AreEqual("Honkey,Tonkey", String.Join(",", l_oAccount.Group));
|
||||
Assert.AreEqual(TINK.Model.User.Account.Permissions.None, l_oAccount.DebugLevel);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_InvalidGroup()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => new TINK.Model.User.Account.Account("a@b", "112", "3330", null, TINK.Model.User.Account.Permissions.None));
|
||||
Assert.Throws<ArgumentException>(() => new TINK.Model.User.Account.Account(null));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.User.Account;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.User.Account
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestAccountExtensions
|
||||
{
|
||||
/// <summary> If no user is logged in filter is not applied. </summary>
|
||||
[Test]
|
||||
public void TestDoFilter_NoUserLoggedIn()
|
||||
{
|
||||
var l_oAccount = MockRepository.GenerateMock<IAccount>();
|
||||
|
||||
l_oAccount.Stub((x) => x.Mail).Return("a@b");
|
||||
l_oAccount.Stub((x) => x.SessionCookie).Return(""); // User is not logged in
|
||||
l_oAccount.Stub((x) => x.Group).Return(new List<string> { "TINK", "FutureType" });
|
||||
|
||||
var l_oSource = new List<string> { "TINK", "Konrad", "FutureType" };
|
||||
|
||||
var l_oResult = l_oAccount.DoFilter(l_oSource);
|
||||
|
||||
Assert.AreEqual(3, l_oResult.ToList().Count);
|
||||
Assert.AreEqual("TINK", l_oResult.ToList()[0]);
|
||||
Assert.AreEqual("Konrad", l_oResult.ToList()[1]);
|
||||
Assert.AreEqual("FutureType", l_oResult.ToList()[2]);
|
||||
}
|
||||
/// <summary> </summary>
|
||||
[Test]
|
||||
public void TestDoFilter()
|
||||
{
|
||||
var l_oAccount = MockRepository.GenerateMock<IAccount>();
|
||||
|
||||
l_oAccount.Stub((x) => x.Mail).Return("a@b");
|
||||
l_oAccount.Stub((x) => x.SessionCookie).Return("123");
|
||||
l_oAccount.Stub((x) => x.Group).Return(new List<string> { "TINK", "FutureType" });
|
||||
|
||||
var l_oSource = new List<string> { "TINK", "Konrad", "FutureType" };
|
||||
|
||||
var l_oResult = l_oAccount.DoFilter(l_oSource);
|
||||
|
||||
Assert.AreEqual(2, l_oResult.ToList().Count);
|
||||
Assert.AreEqual("TINK", l_oResult.ToList()[0]);
|
||||
Assert.AreEqual("FutureType", l_oResult.ToList()[1]);
|
||||
}
|
||||
}
|
||||
}
|
24
TestTINKLib/Fixtures/ObjectTests/User/Account/TestStore.cs
Normal file
24
TestTINKLib/Fixtures/ObjectTests/User/Account/TestStore.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model.User.Account;
|
||||
|
||||
namespace UITest.Fixtures.ObjectTests.User.Account
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestStore
|
||||
{
|
||||
[Test, Explicit("Did never ran, file load exception.")]
|
||||
public void TestLoadSaveRoundtrip()
|
||||
{
|
||||
var l_oStore = new Store("4711");
|
||||
l_oStore.Save(new TINK.Model.User.Account.Account("a@b", "112", "3330", new List<string> { "Honkey", "Tonkey" }, 17));
|
||||
var l_oAccount = l_oStore.Load();
|
||||
Assert.AreEqual("a@b", l_oAccount.Mail);
|
||||
Assert.AreEqual("112", l_oAccount.Pwd);
|
||||
Assert.AreEqual("3330", l_oAccount.SessionCookie);
|
||||
Assert.AreEqual("Honkey,Tonkey", String.Join(",", l_oAccount.Group));
|
||||
Assert.AreEqual(17, l_oAccount.DebugLevel);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Model.User.Account;
|
||||
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestValidator
|
||||
{
|
||||
[Test]
|
||||
public void TestValidateMailAndPasswordDelegate()
|
||||
{
|
||||
Assert.AreEqual(Elements.None, Validator.ValidateMailAndPasswordDelegate(null, null).ValidElement);
|
||||
|
||||
Assert.AreEqual(Elements.None, Validator.ValidateMailAndPasswordDelegate("", null).ValidElement);
|
||||
|
||||
Assert.AreEqual(Elements.None, Validator.ValidateMailAndPasswordDelegate("a", null).ValidElement);
|
||||
|
||||
Assert.AreEqual(Elements.None, Validator.ValidateMailAndPasswordDelegate("a@", null).ValidElement);
|
||||
|
||||
|
||||
Assert.AreEqual(Elements.Mail, Validator.ValidateMailAndPasswordDelegate("a@c", "").ValidElement);
|
||||
|
||||
Assert.AreEqual(Elements.Mail, Validator.ValidateMailAndPasswordDelegate("a@c", "123").ValidElement);
|
||||
|
||||
Assert.AreEqual(Elements.Mail | Elements.Password, Validator.ValidateMailAndPasswordDelegate("a@c", "123456789" /* password */).ValidElement);
|
||||
}
|
||||
}
|
||||
}
|
97
TestTINKLib/Fixtures/ObjectTests/User/TestUser.cs
Normal file
97
TestTINKLib/Fixtures/ObjectTests/User/TestUser.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.Connector;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
|
||||
using TINK.Model.User.Account;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Repository;
|
||||
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestUser
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct_NotLoggedIn_NoUsername()
|
||||
{
|
||||
var l_oStoreMock = new StoreMock(); // Account without user name, password and cookie
|
||||
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"HwId1000000000000");
|
||||
|
||||
Assert.IsFalse(l_oUser.IsLoggedIn);
|
||||
Assert.IsNull(l_oUser.Mail);
|
||||
Assert.IsNull(l_oUser.Password);
|
||||
Assert.IsNull(l_oUser.SessionCookie);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_NotLoggedIn_NoCookie()
|
||||
{
|
||||
var l_oStoreMock = new StoreMock(new Account("John", "123", null, new List<string>())); // Account without session cookie.
|
||||
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789");
|
||||
|
||||
Assert.IsFalse(l_oUser.IsLoggedIn);
|
||||
Assert.AreEqual("John", l_oUser.Mail);
|
||||
Assert.AreEqual("123", l_oUser.Password);
|
||||
Assert.IsNull(l_oUser.SessionCookie);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_LoggedIn()
|
||||
{
|
||||
var l_oStoreMock = new StoreMock(new Account("John", "123", "9512", new List<string> { "TINK" }));
|
||||
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789");
|
||||
|
||||
Assert.IsTrue(l_oUser.IsLoggedIn, "If store does not hold cookie user is considered to not be logged in");
|
||||
|
||||
Assert.AreEqual("John", l_oUser.Mail);
|
||||
Assert.AreEqual("123", l_oUser.Password);
|
||||
Assert.AreEqual("9512", l_oUser.SessionCookie);
|
||||
}
|
||||
|
||||
/// <summary>Test logging in. </summary>
|
||||
[Test]
|
||||
public void TestSetCredentials()
|
||||
{
|
||||
var l_oConnector = new ConnectorCache(
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
new CopriCallsMemory(SampleSets.Set2, 1));
|
||||
|
||||
var l_oStoreMock = new StoreMock(); // Account without user name, password and cookie
|
||||
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"HwId1000000000000");
|
||||
|
||||
Assert.IsFalse(l_oUser.IsLoggedIn);
|
||||
Assert.IsNull(l_oUser.Mail);
|
||||
|
||||
IAccount l_oAccount = l_oConnector.Command.DoLogin(
|
||||
LoginSessionCopriInfo.JavaministerHardwareNr1.Mail,
|
||||
LoginSessionCopriInfo.JavaministerHardwareNr1.Pwd,
|
||||
l_oUser.DeviceId).Result;
|
||||
|
||||
l_oUser.Login(l_oAccount);
|
||||
Assert.IsTrue(l_oUser.IsLoggedIn);
|
||||
|
||||
Assert.AreEqual(LoginSessionCopriInfo.JavaministerHardwareNr1.Mail, l_oUser.Mail);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestTINKLib.Mocks.Connector;
|
||||
using TestTINKLib.Mocks.Device;
|
||||
using TestTINKLib.Mocks.Services;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.View;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
|
||||
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
using TINK.ViewModel.Map;
|
||||
using TINK.ViewModel.Settings;
|
||||
using TINK.ViewModel.Account;
|
||||
using TINK.Services;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using NSubstitute;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Account
|
||||
{
|
||||
public class TestAccountPageViewModel
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct_NotLoggedIn()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
|
||||
var settingsPageViewModel = new AccountPageViewModel(
|
||||
tinkApp,
|
||||
(uri) => { },
|
||||
viewService);
|
||||
|
||||
|
||||
Assert.AreEqual("No user logged in.", settingsPageViewModel.LoggedInInfo);
|
||||
Assert.IsFalse(settingsPageViewModel.IsBookingStateInfoVisible, "No user logged in.");
|
||||
Assert.AreEqual(string.Empty, settingsPageViewModel.BookingStateInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "UnknownCookie", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
|
||||
var settingsPageViewModel = new AccountPageViewModel(
|
||||
tinkApp,
|
||||
(uri) => { },
|
||||
viewService);
|
||||
|
||||
await settingsPageViewModel.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Logged in as a@b at TINK.", settingsPageViewModel.LoggedInInfo);
|
||||
Assert.IsFalse(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
|
||||
Assert.AreEqual(string.Empty, settingsPageViewModel.BookingStateInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_TwoBikes()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var settingsPageViewModel = new AccountPageViewModel(
|
||||
tinkApp,
|
||||
(uri) => { },
|
||||
viewService);
|
||||
|
||||
await settingsPageViewModel.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Logged in as a@b at TINK.", settingsPageViewModel.LoggedInInfo);
|
||||
Assert.IsTrue(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
|
||||
Assert.AreEqual("Aktuell 2 Fahrräder reserviert/ gebucht.", settingsPageViewModel.BookingStateInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_TwoBikes_Offline()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => false, // Offline
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var settingsPageViewModel = new AccountPageViewModel(
|
||||
tinkApp,
|
||||
(uri) => { },
|
||||
viewService);
|
||||
|
||||
await settingsPageViewModel.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Logged in as a@b at TINK.", settingsPageViewModel.LoggedInInfo);
|
||||
Assert.IsTrue(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
|
||||
Assert.AreEqual("Aktuell 2 Fahrräder reserviert/ gebucht. Verbindungsstatus: Offline.", settingsPageViewModel.BookingStateInfo);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_TwoBikes_WebConnectCommunicationError()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
|
||||
uri,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie,
|
||||
mail,
|
||||
server: new CopriProviderHttps(
|
||||
uri,
|
||||
TinkApp.MerchantId,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory(SampleSets.Set2, sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new WebConnectFailureException(msg, new Exception("Source expection."))))),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => false, // Offline
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var settingsPageViewModel = new AccountPageViewModel(
|
||||
tinkApp,
|
||||
(uri) => { },
|
||||
viewService);
|
||||
|
||||
await settingsPageViewModel.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Logged in as a@b at TINK.", settingsPageViewModel.LoggedInInfo);
|
||||
Assert.IsTrue(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
|
||||
Assert.AreEqual("Aktuell 2 Fahrräder reserviert/ gebucht. Verbindungsstatus: Offline.", settingsPageViewModel.BookingStateInfo);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,462 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Bikes.Bike.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Model.State;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBookedDisconnected
|
||||
{
|
||||
/// <summary>
|
||||
/// Test construction of object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Testctor()
|
||||
{
|
||||
var handler = new BookedDisconnected(
|
||||
Substitute.For<IBikeInfoMutable>(),
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => Substitute.For<IConnector>(),
|
||||
Substitute.For<IGeolocation>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
Substitute.For<IViewService>(),
|
||||
Substitute.For<IBikesViewModel>(),
|
||||
Substitute.For<IUser>());
|
||||
|
||||
// Verify prerequisites.
|
||||
Assert.AreEqual("BookedDisconnected", handler.ButtonText);
|
||||
Assert.IsFalse(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNotSupported()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify that nothing happened because request is not supported.
|
||||
Assert.AreEqual("BookedDisconnected", subsequent.ButtonText);
|
||||
Assert.IsFalse(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Booked open
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearch()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns(Task.FromResult(new LockInfoTdo.Builder { State = LockitLockingState.Open }.Build()));
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Booked unknown
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchCalculateAuthKeysFailsWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
connector.Command.CalculateAuthKeys(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("Tst")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Unknown);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler bei Verbinden mit Schloss!", "Internet muss erreichbar sein um Verbindung mit Schloss für gemietetes Rad herzustellen.\r\nContext info\r\nIst WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("BookedDisconnected", handler.ButtonText);
|
||||
Assert.IsFalse(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Booked unknown
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchCalculateAuthKeysFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
connector.Command.CalculateAuthKeys(bike).Returns(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Unknown);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler bei Verbinden mit Schloss!", "Kommunikationsfehler bei Schlosssuche.\r\nException message.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("BookedDisconnected", handler.ButtonText);
|
||||
Assert.IsFalse(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Booked unknown
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchConnectFailsOutOfReachException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns<Task<LockInfoTdo>>(x => { throw new OutOfReachException(); });
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert(
|
||||
"Fehler bei Verbinden mit Schloss!",
|
||||
"Schloss kann erst gefunden werden, wenn gemietetes Rad in der Nähe ist.",
|
||||
"Wiederholen",
|
||||
"Abbrechen");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("BookedDisconnected", handler.ButtonText);
|
||||
Assert.IsFalse(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Booked unknown
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchConnectFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns<Task<LockInfoTdo>>(x => throw new Exception("Exception message.") );
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAdvancedAlert(
|
||||
"Fehler bei Verbinden mit Schloss!",
|
||||
"Lock of rented bike can not be found.",
|
||||
"Exception message.",
|
||||
"Wiederholen",
|
||||
"Abbrechen");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("BookedDisconnected", handler.ButtonText);
|
||||
Assert.IsFalse(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Booked unknown
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchConnectNotOpen()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new BookedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns(new LockInfoTdo.Builder { State = null }.Build());
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler bei Verbinden mit Schloss!", "Schlossstatus des gemieteten Rads konnte nicht ermittelt werden.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("BookedDisconnected", handler.ButtonText);
|
||||
Assert.IsFalse(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,590 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Bikes.Bike.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Model.State;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestDisposableDisconnected
|
||||
{
|
||||
/// <summary>
|
||||
/// Test construction of object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Testctor()
|
||||
{
|
||||
var handler = new DisposableDisconnected(
|
||||
Substitute.For<IBikeInfoMutable>(),
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => Substitute.For<IConnector>(),
|
||||
Substitute.For<IGeolocation>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
Substitute.For<IViewService>(),
|
||||
Substitute.For<IBikesViewModel>(),
|
||||
Substitute.For<IUser>());
|
||||
|
||||
// Verify prerequisites.
|
||||
Assert.AreEqual("Reserve bike", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", handler.LockitButtonText);
|
||||
Assert.IsFalse(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectCancel()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(false));
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No");
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Reserved closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnect()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(),Arg.Any<TimeSpan>())
|
||||
.Returns(Task.FromResult(new LockInfoTdo.Builder { State = LockitLockingState.Closed }.Build())); // Return lock state indicating success
|
||||
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Rent bike {0} and open lock?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Open)); // Return lock state indicating success
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Booking call leads to setting of state to booked.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Opening lock...";
|
||||
locks.Received()[0].OpenAsync(); // Lock must be opened
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Updating lock state...";
|
||||
connector.Command.UpdateLockingStateAsync(bike, null);
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectReserveFailsBookingDeclinedException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoReserve(bike).Returns(x => throw new BookingDeclinedException(7)); // Booking must be performed
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Hint", string.Format("A reservation of bike {0} was rejected because the maximum allowed number of {1} reservations/ rentals had already been made.", 0, 7), "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectReserveFailsWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoReserve(bike).Returns<Task>(x => throw new WebConnectFailureException("Context info.", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Verbingungsfehler beim Reservieren des Rads!", "Context info.\r\nIst WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectReserveFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoReserve(bike).Returns<Task>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler beim Reservieren des Rads!", "Exception message.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Reserved unknown.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectConnectOutOfReachException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>()).Returns<LockInfoTdo>(x => throw new OutOfReachException());
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Disconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "Schloss außerhalb Reichweite";
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Reserved unknown.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectConnectException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>()).Returns<LockInfoTdo>(x => throw new Exception("Exception message."));
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Disconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "Schloss nicht gefunden";
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Reserve bike.
|
||||
/// Final state: Reserved unknown.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestReserveAndConnectConnectStateUnknown()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Reserve bike Nr. 0 free of charge for 15 min?", "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Unknown); // Connect did not throw an exception but lock state is still unknown.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reserving bike...";
|
||||
connector.Command.DoReserve(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNotsupported()
|
||||
{
|
||||
var handler = new DisposableDisconnected(
|
||||
Substitute.For<IBikeInfoMutable>(),
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => Substitute.For<IConnector>(),
|
||||
Substitute.For<IGeolocation>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
Substitute.For<IViewService>(),
|
||||
Substitute.For<IBikesViewModel>(),
|
||||
Substitute.For<IUser>());
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,442 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Bikes.Bike.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Model.State;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestDisposableOpen
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Test construction of object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Testctor()
|
||||
{
|
||||
var handler = new DisposableOpen (
|
||||
Substitute.For<IBikeInfoMutable>(),
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => Substitute.For<IConnector>(),
|
||||
Substitute.For<IGeolocation>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
Substitute.For<IViewService>(),
|
||||
Substitute.For<IBikesViewModel>(),
|
||||
Substitute.For<IUser>());
|
||||
|
||||
// Verify prerequisites.
|
||||
Assert.AreEqual("Rent bike or close lock", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual(nameof(DisposableOpen), handler.LockitButtonText);
|
||||
Assert.IsFalse(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Lock bike.
|
||||
/// Final state: Disposable Closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLock()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Fahrrad Nr. 0 mieten oder Schloss schließen?", "Mieten", "Schloss schließen").Returns(Task.FromResult(false));
|
||||
|
||||
locks[0].CloseAsync().Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Disconnecting lock...";
|
||||
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Lock bike.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockCloseFailsOutOfReachExcption()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Fahrrad Nr. 0 mieten oder Schloss schließen?", "Mieten", "Schloss schließen").Returns(Task.FromResult(false));
|
||||
|
||||
locks[0].CloseAsync().Returns<Task<LockitLockingState?>>(x => throw new OutOfReachException());
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Lock can not be closed!", "Lock cannot be closed until bike is near.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual(nameof(DisposableDisconnected), subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Lock bike.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockCloseFailsExcption()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Fahrrad Nr. 0 mieten oder Schloss schließen?", "Mieten", "Schloss schließen").Returns(Task.FromResult(false));
|
||||
|
||||
locks[0].CloseAsync().Returns<Task<LockitLockingState?>>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Lock can not be closed!", "Exception message.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual(nameof(DisposableDisconnected), subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Lock bike.
|
||||
/// Final state: Booked Open.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDoBook()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Fahrrad Nr. 0 mieten oder Schloss schließen?", "Mieten", "Schloss schließen").Returns(Task.FromResult(true));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike);
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Lock bike.
|
||||
/// Final state: Disposabled Closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDoBookDoBookFailsWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Fahrrad Nr. 0 mieten oder Schloss schließen?", "Mieten", "Schloss schließen").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoBook(bike).Returns(x => throw new WebConnectFailureException("Context info.", new Exception("chub")));
|
||||
|
||||
locks[0].CloseAsync().Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert(
|
||||
"Connection error when renting the bike!",
|
||||
string.Format("Attention: Lock is closed!\r\n{0}\r\n{1}", "Context info.", "Ist WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?"),
|
||||
"OK");
|
||||
bikesViewModel.ActionText = "Verschließe Schloss...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Disconnecting lock...";
|
||||
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Lock bike.
|
||||
/// Final state: Disposabled Closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDoBookDoBookFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new DisposableOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Fahrrad Nr. 0 mieten oder Schloss schließen?", "Mieten", "Schloss schließen").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoBook(bike).Returns(x => throw new Exception("Exception message."));
|
||||
|
||||
locks[0].CloseAsync().Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Error when renting the bike!", "Attention: Lock is closed!\r\nException message.", "OK");
|
||||
bikesViewModel.ActionText = "Verschließe Schloss...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Disconnecting lock...";
|
||||
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,752 @@
|
|||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Bikes.Bike.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Model.State;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
||||
using Newtonsoft.Json;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
public class TestReservedDisconnected
|
||||
{
|
||||
/// <summary>
|
||||
/// Test construction of object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Testctor()
|
||||
{
|
||||
var handler = new ReservedDisconnected(
|
||||
Substitute.For<IBikeInfoMutable>(),
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => Substitute.For<IConnector>(),
|
||||
Substitute.For<IGeolocation>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
Substitute.For<IViewService>(),
|
||||
Substitute.For<IBikesViewModel>(),
|
||||
Substitute.For<IUser>());
|
||||
|
||||
// Verify prerequisites.
|
||||
Assert.AreEqual("Cancel bike reservation", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Comment: User deceide to abort cancelling (user is ased whether to really cancel)
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCancelReservationCancel()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(false));
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No");
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Final state: Disposable.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCancelReservation()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Disconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Comment: Exception is thrown.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCancelReservationDoCancelReservationInvalidAuthorizationResponseException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
var l_oResponse = JsonConvert.DeserializeObject<AuthorizationResponse>(@"
|
||||
{
|
||||
""response"" : ""authorization"",
|
||||
""authcookie"" : ""4da3044c8657a04ba60e2eaa753bc51a"",
|
||||
""user_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}");
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", l_oResponse));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Disconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler beim Aufheben der Reservierung!", "Kann Benutzer mustermann@server.de nicht anmelden. Mailadresse unbekannt oder Passwort ungültig.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Comment: Canceling reservation fails.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCancelReservationDoCancelReservationWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("chub")));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Disconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Verbingungsfehler beim Aufheben der Reservierung!", "Context info\r\nIst WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Comment: Canceling reservation fails.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCancelReservationDoCancelReservationException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Disconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler beim Aufheben der Reservierung!", "Exception message.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: reserved closed
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearch()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns(Task.FromResult(new LockInfoTdo.Builder { State = LockitLockingState.Closed }.Build()));
|
||||
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Rent bike {0} and open lock?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Open)); // Return lock state indicating success
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Booking call leads to setting of state to booked.
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike); // Booking must be performed
|
||||
bikesViewModel.ActionText = "Opening lock...";
|
||||
locks.Received()[0].OpenAsync(); // Lock must be opened
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Updating lock state...";
|
||||
connector.Command.UpdateLockingStateAsync(bike, null);
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchCalculateAuthKeysFailsWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
connector.Command.CalculateAuthKeys(bike).Returns(x => throw new WebConnectFailureException("Context info.", new Exception("Tst")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Unknown);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler bei Verbinden mit Schloss!", "Internet muss erreichbar sein um Verbindung mit Schloss für reserviertes Rad herzustellen.\r\nContext info.\r\nIst WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchCalculateAuthKeysFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
connector.Command.CalculateAuthKeys(bike).Returns(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Unknown);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler bei Verbinden mit Schloss!", "Kommunikationsfehler bei Schlosssuche.\r\nException message.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchConnectFailsOutOfReachException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns<Task<LockInfoTdo>>(x => { throw new OutOfReachException(); });
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert(
|
||||
"Fehler bei Verbinden mit Schloss!",
|
||||
"Schloss kann erst gefunden werden, wenn reserviertes Rad in der Nähe ist.",
|
||||
"Wiederholen",
|
||||
"Abbrechen");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchConnectFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns<Task<LockInfoTdo>>(x => throw new Exception("Execption message."));
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAdvancedAlert(
|
||||
"Fehler bei Verbinden mit Schloss!",
|
||||
"Lock of reserved bike can not be found.",
|
||||
"Execption message.",
|
||||
"Wiederholen",
|
||||
"Abbrechen");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Search.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestSearchConnectNotOpen()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
var handler = new ReservedDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
|
||||
.Returns(new LockInfoTdo.Builder { State = null }.Build());
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
var subsequent = handler.HandleRequestOption2().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Request server...";
|
||||
connector.Command.CalculateAuthKeys(bike);
|
||||
bikesViewModel.ActionText = "Searching lock...";
|
||||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler bei Verbinden mit Schloss!", "Schlossstatus des reservierten Rads konnte nicht ermittelt werden.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", handler.LockitButtonText);
|
||||
Assert.IsTrue(handler.IsLockitButtonVisible);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,671 @@
|
|||
using Newtonsoft.Json;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Bikes.Bike.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Services.BluetoothLock.Exception;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Model.State;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestReservedOpen
|
||||
{
|
||||
/// <summary>
|
||||
/// Test construction of object.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Testctor()
|
||||
{
|
||||
var handler = new ReservedOpen(
|
||||
Substitute.For<IBikeInfoMutable>(),
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => Substitute.For<IConnector>(),
|
||||
Substitute.For<IGeolocation>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
Substitute.For<IViewService>(),
|
||||
Substitute.For<IBikesViewModel>(),
|
||||
Substitute.For<IUser>());
|
||||
|
||||
// Verify prerequisites.
|
||||
Assert.AreEqual("Rad zurückgeben oder mieten", handler.ButtonText);
|
||||
Assert.IsTrue(handler.IsButtonVisible);
|
||||
Assert.AreEqual("Alarm/ Sounds verwalten", handler.LockitButtonText);
|
||||
Assert.IsFalse(handler.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: User books bike.
|
||||
/// Final state: Booked.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestBook()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(false));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike);
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: User books bike.
|
||||
/// Final state: Reserved closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestBookBookFailsWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(false));
|
||||
|
||||
connector.Command.DoBook(bike).Returns(x => throw new WebConnectFailureException("Context info.", new Exception("Tst")));
|
||||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert(
|
||||
"Connection error when renting the bike!",
|
||||
string.Format("Attention: Lock is closed!\r\n{0}\r\n{1}", "Context info.", "Ist WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?"),
|
||||
"OK");
|
||||
bikesViewModel.ActionText = "Wiederverschließe Schloss...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Open lock & rent bike", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: User books bike.
|
||||
/// Final state: Reserved closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestBookBookFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(false));
|
||||
|
||||
connector.Command.DoBook(bike).Returns(x => throw new Exception("Exception message."));
|
||||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Reading charging level...";
|
||||
locks[0].GetBatteryPercentageAsync();
|
||||
bikesViewModel.ActionText = "Renting bike...";
|
||||
connector.Command.DoBook(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Error when renting the bike!", "Attention: Lock is closed!\r\nException message.", "OK");
|
||||
bikesViewModel.ActionText = "Wiederverschließe Schloss...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Open lock & rent bike", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Close lock and cancel reservation.
|
||||
/// Final state: Booked.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockAndCancelReservation()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike);
|
||||
bikesViewModel.ActionText = "Disconnecting lock...";
|
||||
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Close lock and cancel reservation.
|
||||
/// Final state: Reserved open.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockAndCancelReservationCloseFailsOutOfReachException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(
|
||||
string.Empty,
|
||||
"Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?",
|
||||
"Zurückgeben",
|
||||
"Mieten").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => { throw new OutOfReachException(); });
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert(
|
||||
"Lock can not be closed!",
|
||||
"Lock cannot be closed until bike is near.\r\nPlease try again to close bike or report bike to support!",
|
||||
"OK");
|
||||
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Close lock and cancel reservation.
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockAndCancelReservationCloseFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(
|
||||
string.Empty,
|
||||
"Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?",
|
||||
"Zurückgeben",
|
||||
"Mieten").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => { throw new Exception("Exception message."); });
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert(
|
||||
"Lock can not be closed!",
|
||||
"Please try to lock again or report bike to support!\r\nException message.",
|
||||
"OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("Cancel bike reservation", subsequent.ButtonText);
|
||||
Assert.IsTrue(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
|
||||
Assert.IsTrue(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Close lock and cancel reservation.
|
||||
/// Final state: Reserved closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockAndCancelReservationCancelReservationInvalidAuthorizationResponseException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
var response = JsonConvert.DeserializeObject<AuthorizationResponse>(@"
|
||||
{
|
||||
""response"" : ""authorization"",
|
||||
""authcookie"" : ""4da3044c8657a04ba60e2eaa753bc51a"",
|
||||
""user_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}");
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", response));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler beim Aufheben der Reservierung!", "Kann Benutzer mustermann@server.de nicht anmelden. Mailadresse unbekannt oder Passwort ungültig.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("InvalidState", subsequent.ButtonText);
|
||||
Assert.IsFalse(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("InvalidState", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Close lock and cancel reservation.
|
||||
/// Final state: Reserved closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockAndCancelReservationCancelReservationWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Verbingungsfehler beim Aufheben der Reservierung!", "Context info\r\nIst WLAN verfügbar/ Mobilfunknetz vefügbar und mobile Daten aktiviert / ... ?", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("InvalidState", subsequent.ButtonText);
|
||||
Assert.IsFalse(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("InvalidState", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Close lock and cancel reservation.
|
||||
/// Final state: Reserved closed.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestCloseLockAndCancelReservationCancelReservationException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocation>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
var handler = new ReservedOpen(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnexted) => connector,
|
||||
geolocation,
|
||||
locks,
|
||||
() => pollingManager,
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService,
|
||||
bikesViewModel,
|
||||
activeUser);
|
||||
|
||||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(true));
|
||||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message.", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
|
||||
bikesViewModel.ActionText = "One moment please...";
|
||||
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
|
||||
bikesViewModel.ActionText = "Closing lock...";
|
||||
locks[0].CloseAsync();
|
||||
bikesViewModel.ActionText = "Canceling reservation...";
|
||||
connector.Command.DoCancelReservation(bike);
|
||||
bikesViewModel.ActionText = "";
|
||||
viewService.DisplayAlert("Fehler beim Aufheben der Reservierung!", "Exception message.", "OK");
|
||||
bikesViewModel.ActionText = "Updating...";
|
||||
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
|
||||
bikesViewModel.ActionText = "";
|
||||
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
|
||||
});
|
||||
|
||||
// Verify state after action
|
||||
Assert.AreEqual("InvalidState", subsequent.ButtonText);
|
||||
Assert.IsFalse(subsequent.IsButtonVisible);
|
||||
Assert.AreEqual("InvalidState", subsequent.LockitButtonText);
|
||||
Assert.IsFalse(subsequent.IsLockitButtonVisible);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TestTINKLib.Mocks.Services;
|
||||
using TINK.Model.Bike.BluetoothLock;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.State;
|
||||
using TINK.Model.User;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock;
|
||||
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
/// <summary>
|
||||
/// Moved to TestShareeLib (.Net Core)
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class TestRequestHandlerFactory
|
||||
{
|
||||
[Test]
|
||||
public void TestCreate()
|
||||
{
|
||||
// Verify handler for disposable bike.
|
||||
var bike = new BikeInfoMutable(new BikeInfo("22", 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "12"));
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, bike.State.Value);
|
||||
Assert.AreEqual(LockingState.Disconnected, bike.LockInfo.State);
|
||||
Assert.AreEqual(
|
||||
typeof(DisposableDisconnected),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
() => false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */ ,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
|
||||
// Verify handler for requested bike with state unknown.
|
||||
bike = new BikeInfoMutable(new BikeInfo("22", 0 /* lock Id */, new Guid(), /*K User*/ null, /*K Admin*/ null, /*K Seed*/ null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>(), TINK.Model.Bike.WheelType.Mono, TINK.Model.Bike.TypeOfBike.Allround));
|
||||
Assert.AreEqual(
|
||||
typeof(ReservedDisconnected),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
() => false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
|
||||
// Verify handler for requested bike with state closed.
|
||||
bike = new BikeInfoMutable(new BikeInfo("22", 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>(), TINK.Model.Bike.WheelType.Mono, TINK.Model.Bike.TypeOfBike.Allround));
|
||||
bike.LockInfo.State = LockingState.Closed;
|
||||
Assert.AreEqual(
|
||||
typeof(ReservedClosed),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
() => false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
|
||||
// Verify handler for requested bike with state open.
|
||||
bike = new BikeInfoMutable(new BikeInfo("22", 0 /* lock Id*/, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>(), TINK.Model.Bike.WheelType.Mono, TINK.Model.Bike.TypeOfBike.Allround));
|
||||
bike.LockInfo.State = LockingState.Open;
|
||||
Assert.AreEqual(
|
||||
typeof(ReservedOpen),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
() => false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
|
||||
// Verify handler for booked bike with state closed.
|
||||
bike = new BikeInfoMutable(new BikeInfo("22", 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>(), TINK.Model.Bike.WheelType.Mono, TINK.Model.Bike.TypeOfBike.Allround));
|
||||
bike.LockInfo.State = LockingState.Closed;
|
||||
Assert.AreEqual(
|
||||
typeof(BookedClosed),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
() => false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
|
||||
// Verify handler for booked bike with state open.
|
||||
bike = new BikeInfoMutable(new BikeInfo("22", 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>(), TINK.Model.Bike.WheelType.Mono, TINK.Model.Bike.TypeOfBike.Allround));
|
||||
bike.LockInfo.State = LockingState.Open;
|
||||
Assert.AreEqual(
|
||||
typeof(BookedOpen),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
() => false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
|
||||
// Verify handler for booked bike with state unknown.
|
||||
bike = new BikeInfoMutable(new BikeInfo("22", 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>(), TINK.Model.Bike.WheelType.Mono, TINK.Model.Bike.TypeOfBike.Allround));
|
||||
|
||||
Assert.AreEqual(
|
||||
typeof(BookedDisconnected),
|
||||
RequestHandlerFactory.Create(
|
||||
bike,
|
||||
()=> false, // isConnectedDelegate
|
||||
(connected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // LockService
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null /* viewService */,
|
||||
MockRepository.GenerateStub<IBikesViewModel>(),
|
||||
MockRepository.GenerateStub<IUser>()).GetType());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.ViewModel.Login;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.CopriWebView
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestManageAccountViewModel
|
||||
{
|
||||
[Test]
|
||||
public void TestUrl()
|
||||
{
|
||||
var viewModel = new ManageAccountViewModel("Keks", "Merchant", "Hosti");
|
||||
Assert.AreEqual("https://Hosti?sessionid=KeksMerchant", viewModel.Uri);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.ViewModel.CopriWebView;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.CopriWebView
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestPasswordForgottonViewModel
|
||||
{
|
||||
[Test]
|
||||
public void TestUrl()
|
||||
{
|
||||
var viewModel = new PasswordForgottonViewModel("Merchant", "Hosti");
|
||||
Assert.AreEqual("https://Hosti/app/Account?sessionid=Merchant", viewModel.Uri);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUrl_TINKLive()
|
||||
{
|
||||
var viewModel = new PasswordForgottonViewModel("Merchant", "app.tink-konstanz.de");
|
||||
Assert.AreEqual("https://app.tink-konstanz.de/tinkapp/Account?sessionid=Merchant", viewModel.Uri);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUrl_TINK()
|
||||
{
|
||||
var viewModel = new PasswordForgottonViewModel("Merchant", "tinkwwp.copri-bike.de");
|
||||
Assert.AreEqual("https://tinkwwp.copri-bike.de/tinkapp/Account?sessionid=Merchant", viewModel.Uri);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using NUnit.Framework;
|
||||
using TINK.ViewModel.Info;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Info
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestInfoViewModel
|
||||
{
|
||||
[Test]
|
||||
public void TestOnAppearing()
|
||||
{
|
||||
var viewModel = new InfoViewModel("Hosti", false, (url) => string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model;
|
||||
|
||||
using TINK.ViewModel.Map;
|
||||
namespace UITest.Fixtures.ObjectTests.ViewModel.Map
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestMapPageViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Verifies that if Konrad is turned off in settings map page filter does no more contain Konrad option.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_NoKonrad_TinkOnKonradOff()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "TINK" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(1, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that if Konrad is turned off in settings map page filter does no more contain Konrad option.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_NoKonrad_TinkOffKonradOn()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "TINK" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(1, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that if TINK.* is turned off in settings map page filter does no more contain TINK option.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_NoTink_TinkOnKonradOff()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "Konrad" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(1, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that if Konrad is turned on in settings map page filter is updated with entry Konrad.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_TinkOn()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(2, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.Off, l_oDict["TINK"]);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that if Konrad is turned on in settings map page filter is updated with entry Konrad.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_TinkOff()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(2, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.Off, l_oDict["TINK"]);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that map page filters are not touched if state is consitend.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_AllOn_KonradActivated()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(2, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.Off, l_oDict["TINK"]);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that map page filters are not touched if state is consitend..
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_AllOn_TinkActivated()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
|
||||
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
|
||||
|
||||
Assert.AreEqual(2, l_oDict.Count);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
|
||||
Assert.AreEqual(FilterState.Off, l_oDict["Konrad"]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that map page filters are not touched if state is consitend.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestGetFilterDictinaryMapPage_NullFilter()
|
||||
{
|
||||
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
|
||||
null);
|
||||
|
||||
Assert.AreEqual(2, l_oDict.Count, "Do not apply any filter if filter value null is detected.");
|
||||
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
|
||||
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
|
||||
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
|
||||
Assert.AreEqual(FilterState.Off, l_oDict["Konrad"]);
|
||||
|
||||
l_oDict = GroupFilterMapPageHelper.CreateUpdated(
|
||||
null,
|
||||
null);
|
||||
|
||||
Assert.IsNull(l_oDict, "Do not apply any filter if filter value null is detected.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDoToggle()
|
||||
{
|
||||
var l_oFilter = new TinkKonradToggleViewModel(new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }));
|
||||
|
||||
l_oFilter = new TinkKonradToggleViewModel(l_oFilter.FilterDictionary). DoToggle();
|
||||
|
||||
Assert.AreEqual("Konrad", l_oFilter.CurrentFilter);
|
||||
|
||||
l_oFilter = new TinkKonradToggleViewModel(l_oFilter.FilterDictionary).DoToggle();
|
||||
|
||||
Assert.AreEqual("TINK", l_oFilter.CurrentFilter);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,528 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TestTINKLib.Mocks.Connector;
|
||||
using TestTINKLib.Mocks.Device;
|
||||
using TestTINKLib.Mocks.Services;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel.Map;
|
||||
using Xamarin.Forms;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
using TINK.ViewModel.Settings;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Services;
|
||||
using NSubstitute;
|
||||
|
||||
namespace TestTINKLib.Fixtures.UseCases.Startup
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestMapPageViewModel
|
||||
{
|
||||
[Test]
|
||||
public async Task TestConstruct()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.IsNull(viewModel.Exception);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(8, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "4").Icon.Id.Contains("Green"),
|
||||
"Station 4 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Red"),
|
||||
"Station 31 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
|
||||
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are shown.");
|
||||
|
||||
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are hidden.");
|
||||
|
||||
var statusInfoText = viewModel.StatusInfoText;
|
||||
Assert.That(
|
||||
statusInfoText,
|
||||
Does.Contain("Updating...").Or.Contain(""),
|
||||
$"Unexpected text {statusInfoText} detected.",
|
||||
"Text might be \"Updating...\" or empty depending on acivity of update thread.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_KonradActive()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.IsNull(viewModel.Exception);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(2, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Green"),
|
||||
"Station 5 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "14").Icon.Id.Contains("Red"),
|
||||
"Station 14 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
|
||||
Assert.AreEqual(Color.Gray, viewModel.TinkColor, "TINK bikes are hidden.");
|
||||
|
||||
Assert.AreEqual(Color.Red, viewModel.KonradColor, "Konrad bikes are shown.");
|
||||
|
||||
Assert.IsTrue(
|
||||
new[] { "Updating...", "" }.Contains(viewModel.StatusInfoText),
|
||||
"Text might be \"Updating...\" or empty depending on acivity of update thread.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_KonradOnly()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "Konrad", FilterState.On } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173)); // Current app version. Must be larger or equal 3.0.173 to
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.IsNull(viewModel.Exception);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(2, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Green"),
|
||||
"Station 5 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "14").Icon.Id.Contains("Red"),
|
||||
"Station 14 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsFalse(viewModel.IsToggleVisible, "TINK and Konrad is deactivated from settings.");
|
||||
|
||||
Assert.IsTrue(
|
||||
new[] { "Updating...", "" }.Contains(viewModel.StatusInfoText),
|
||||
"Text might be \"Updating...\" or empty depending on acivity of update thread.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_TinkOnly()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173));
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.IsNull(viewModel.Exception);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(8, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "4").Icon.Id.Contains("Green"),
|
||||
"Station 4 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Red"),
|
||||
"Station 31 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsFalse(viewModel.IsToggleVisible, "TINK and Konrad is deactivated from settings.");
|
||||
|
||||
Assert.IsTrue(
|
||||
new[] { "Updating...", "" }.Contains(viewModel.StatusInfoText),
|
||||
"Text might be \"Updating...\" or empty depending on acivity of update thread.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_Offline()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { FilterHelper.FILTERKONRAD, FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => false,
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173)); // Current app version. Must be larger or equal 3.0.173 to
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.IsNull(viewModel.Exception);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(8, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "4").Icon.Id.Contains("Green"),
|
||||
"Station 4 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Red"),
|
||||
"Station 31 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
|
||||
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are hidden.");
|
||||
|
||||
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are shown.");
|
||||
|
||||
|
||||
Assert.AreEqual("Offline.", viewModel.StatusInfoText);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_WebConnectCommunicationError()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { FilterHelper.FILTERKONRAD, FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
true /* IsReportLevelVerbose */,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
|
||||
uri,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie,
|
||||
mail,
|
||||
server: new CopriProviderHttps(
|
||||
uri,
|
||||
TinkApp.MerchantId,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory(sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new WebConnectFailureException(msg, new Exception("Source expection."))))),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => false,
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173)); // Current app version. Must be larger or equal 3.0.173 to
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.AreEqual(
|
||||
"Simulated error thrown at GetStationsAsync.",
|
||||
viewModel.Exception.Message);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(8, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "4").Icon.Id.Contains("Green"),
|
||||
"Station 4 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Red"),
|
||||
"Station 31 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
|
||||
Assert.AreEqual(Color.Blue, viewModel.TinkColor, "TINK bikes are hidden.");
|
||||
|
||||
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are shown.");
|
||||
|
||||
Assert.AreEqual("Connection interrupted, server unreachable.", viewModel.StatusInfoText);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_GeneralPurposeCommunicationError()
|
||||
{
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { FilterHelper.FILTERKONRAD, FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://tinkwwp.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
true /* IsReportLevelVerbose */,
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
|
||||
uri,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie,
|
||||
mail,
|
||||
server: new CopriProviderHttps(
|
||||
uri,
|
||||
TinkApp.MerchantId,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory(sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new Exception(msg)))),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => false,
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173)); // Current app version. Must be larger or equal 3.0.173 to
|
||||
|
||||
|
||||
var viewService = MockRepository.GenerateStub<IViewService>();
|
||||
var navigationService = MockRepository.GenerateStub<INavigation>();
|
||||
|
||||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
new PermissionsMock(),
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocation>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
||||
try
|
||||
{
|
||||
await viewModel.OnAppearing(); // Is called when page shows.
|
||||
|
||||
Assert.AreEqual(
|
||||
"Simulated error thrown at GetStationsAsync.",
|
||||
viewModel.Exception.Message);
|
||||
|
||||
// Verify pins on map
|
||||
Assert.AreEqual(8, viewModel.Pins.Count);
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "4").Icon.Id.Contains("Green"),
|
||||
"Station 4 must be marked green because there is are bike.");
|
||||
Assert.IsTrue(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Tag.ToString() == "31").Icon.Id.Contains("Red"),
|
||||
"Station 31 must be marked red because there is no bike.");
|
||||
|
||||
// Verify buttons
|
||||
Assert.IsTrue(viewModel.IsToggleVisible, "TINK and Konrad are activated in settings.");
|
||||
Assert.AreEqual(Color.Blue , viewModel.TinkColor, "TINK bikes are hidden.");
|
||||
|
||||
Assert.AreEqual(Color.Gray, viewModel.KonradColor, "Konrad bikes are shown.");
|
||||
|
||||
Assert.AreEqual("Connection interrupted.", viewModel.StatusInfoText);
|
||||
}
|
||||
finally
|
||||
{
|
||||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Model;
|
||||
using TINK.ViewModel.Settings;
|
||||
|
||||
|
||||
namespace UITest.Fixtures.ObjectTests.ViewModel.Settings
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestFilterCollectionMutable
|
||||
{
|
||||
[Test]
|
||||
public void TestConstruct_NoConradAccount()
|
||||
{
|
||||
var l_oColl = new SettingsBikeFilterViewModel(
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> {
|
||||
{"TINK", FilterState.On },
|
||||
{"Konrad", FilterState.On}
|
||||
}),
|
||||
new List<string> { "TINK" });
|
||||
|
||||
Assert.AreEqual("TINK", l_oColl[0].Key);
|
||||
Assert.IsTrue(l_oColl[0].IsActivated);
|
||||
Assert.IsTrue(l_oColl[0].IsEnabled);
|
||||
|
||||
Assert.AreEqual("Konrad", l_oColl[1].Key);
|
||||
Assert.IsFalse(l_oColl[1].IsActivated, "Konrad must be off if user is not part of group.");
|
||||
Assert.IsFalse(l_oColl[1].IsEnabled, "Konrad must be disabled if user is not part of group.");
|
||||
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["Konrad"], "Filter state must be preserved.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_ConradAccount()
|
||||
{
|
||||
var l_oColl = new SettingsBikeFilterViewModel(
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> {
|
||||
{"TINK", FilterState.On },
|
||||
{"Konrad", FilterState.On}
|
||||
}),
|
||||
new List<string> { "TINK", "Konrad" });
|
||||
|
||||
Assert.AreEqual("TINK", l_oColl[0].Key);
|
||||
Assert.IsTrue(l_oColl[0].IsActivated);
|
||||
Assert.IsTrue(l_oColl[0].IsEnabled);
|
||||
|
||||
Assert.AreEqual("Konrad", l_oColl[1].Key);
|
||||
Assert.IsTrue(l_oColl[1].IsActivated);
|
||||
Assert.IsTrue(l_oColl[1].IsEnabled);
|
||||
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["Konrad"], "Filter state must be preserved.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_TurnOff()
|
||||
{
|
||||
var l_oColl = new SettingsBikeFilterViewModel(
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> {
|
||||
{"TINK", FilterState.On },
|
||||
{"Konrad", FilterState.On}
|
||||
}),
|
||||
new List<string> { "TINK", "Konrad" });
|
||||
|
||||
// Check prerequisites.
|
||||
Assert.AreEqual("TINK", l_oColl[0].Key);
|
||||
Assert.IsTrue(l_oColl[0].IsActivated);
|
||||
Assert.IsTrue(l_oColl[0].IsEnabled);
|
||||
|
||||
Assert.AreEqual("Konrad", l_oColl[1].Key);
|
||||
Assert.IsTrue(l_oColl[1].IsActivated);
|
||||
Assert.IsTrue(l_oColl[1].IsEnabled);
|
||||
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["Konrad"], "Filter state must be preserved.");
|
||||
|
||||
// Turn filter konrad off.
|
||||
l_oColl[1].IsActivated = false;
|
||||
|
||||
// Verify changes.
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["TINK"]);
|
||||
Assert.AreEqual(FilterState.Off, l_oColl.FilterCollection["Konrad"], "Filter state must be preserved.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestConstruct_NoUserLoggedIn()
|
||||
{
|
||||
var l_oColl = new SettingsBikeFilterViewModel(
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> {
|
||||
{"TINK", FilterState.On },
|
||||
{"Konrad", FilterState.On}
|
||||
}),
|
||||
null);
|
||||
|
||||
// Check prerequisites.
|
||||
Assert.AreEqual("TINK", l_oColl[0].Key);
|
||||
Assert.IsTrue(l_oColl[0].IsActivated);
|
||||
Assert.IsTrue(l_oColl[0].IsEnabled);
|
||||
|
||||
Assert.AreEqual("Konrad", l_oColl[1].Key);
|
||||
Assert.IsTrue(l_oColl[1].IsActivated);
|
||||
Assert.IsTrue(l_oColl[1].IsEnabled);
|
||||
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["TINK"]);
|
||||
Assert.AreEqual(FilterState.On, l_oColl.FilterCollection["Konrad"], "Filter state must be preserved.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.ViewModel;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBikeAtStationInUseStateInfoProvider
|
||||
{
|
||||
[Test]
|
||||
public void TestGetReservedInfo()
|
||||
{
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(null), Is.EqualTo("Max. reservation time of 15 minutes expired."));
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(null, code: "Code123"), Is.Not.Null);
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(3), code: "Code123"), Is.Not.Null);
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(60)), Is.EqualTo("Still 1 minutes reserved."));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test()
|
||||
{
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetBookedInfo(null), Is.EqualTo("Bike is rented."));
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetBookedInfo(DateTime.Parse("2020-12-19 0:22"), code: "Code123"), Is.Not.Null);
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetBookedInfo(DateTime.Parse("2020-12-19 0:22"), code: "Code123"), Is.EqualTo("Code Code123, rented since 19. December 00:22."));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.ViewModel;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using TINK.Model.State;
|
||||
using Rhino.Mocks;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using BikeInfoMutable = TINK.Model.Bike.BC.BikeInfoMutable;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace UITest.Fixtures.ViewModel
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestBikeAtStationViewModel
|
||||
{
|
||||
private class BikeInfoMutable : TINK.Model.Bike.BC.BikeInfoMutable
|
||||
{
|
||||
public BikeInfoMutable(
|
||||
string p_iId,
|
||||
bool p_bIsDemo = false,
|
||||
IEnumerable<string> p_oGroup = null,
|
||||
WheelType? p_eWheelType = null,
|
||||
TypeOfBike? p_eTypeOfBike = null,
|
||||
string description = null,
|
||||
string p_strCurrentStationName = null,
|
||||
Uri operatorUri = null,
|
||||
Func<DateTime> p_oDateTimeProvider = null,
|
||||
IStateInfo stateInfo = null) : base(p_iId, p_bIsDemo, p_oGroup, p_eWheelType, p_eTypeOfBike, description, p_strCurrentStationName, operatorUri, null, p_oDateTimeProvider, stateInfo)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_NotLoggedIn()
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable("2", false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo);
|
||||
|
||||
var l_oStoreMock = new StoreMock(); // Account without user name, password and cookie
|
||||
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789"); // Device identifier
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oBike.State.Value);
|
||||
Assert.IsFalse(l_oUser.IsLoggedIn);
|
||||
|
||||
// Verify view model.
|
||||
var l_oViewModel = new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
l_oBike,
|
||||
l_oUser,
|
||||
new MyBikeInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>());
|
||||
|
||||
Assert.AreEqual("2", l_oViewModel.Name);
|
||||
Assert.AreEqual("", l_oViewModel.DisplayId);
|
||||
Assert.AreEqual("2", l_oViewModel.Id);
|
||||
Assert.AreEqual("Available.", l_oViewModel.StateText);
|
||||
Assert.AreEqual(Color.Default, l_oViewModel.StateColor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Reserved()
|
||||
{
|
||||
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Reserved(
|
||||
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
bike,
|
||||
user,
|
||||
new BikeAtStationInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()));
|
||||
|
||||
Assert.AreEqual("Still 15 minutes reserved.", l_oViewModel.StateText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_ReservedWithCopriConnect()
|
||||
{
|
||||
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_ReservedWithCopriConnect(
|
||||
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
bike,
|
||||
user,
|
||||
new BikeAtStationInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()));
|
||||
|
||||
Assert.AreEqual("Code 4asdfA, still 7 minutes reserved.", l_oViewModel.StateText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Booked()
|
||||
{
|
||||
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Booked(
|
||||
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
bike,
|
||||
user,
|
||||
new BikeAtStationInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()));
|
||||
|
||||
Assert.AreEqual(
|
||||
$"Code 4asdfA, rented since {new DateTime(2018, 10, 24, 21, 49, 00).ToString("dd. MMMM HH:mm")}.",
|
||||
l_oViewModel.StateText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_ReservedBySomeoneElse()
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable("2", false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, "Test description", "3");
|
||||
|
||||
l_oBike.State.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
new DateTime(2017, 10, 24, 21, 49, 3),
|
||||
"ragu@gnu-systems.de",
|
||||
"4asdfA");
|
||||
|
||||
var l_oStoreMock = new StoreMock(new Account("john@long", "123456789" /* password */, "987654321" /* session cookie */, new List<string> { "TINK" }));
|
||||
|
||||
var l_oViewModel = new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
l_oBike,
|
||||
new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789"), // Device id
|
||||
new BikeAtStationInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>());
|
||||
|
||||
Assert.AreEqual("Test description", l_oViewModel.Name);
|
||||
Assert.AreEqual("2", l_oViewModel.DisplayId);
|
||||
Assert.AreEqual("2", l_oViewModel.Id);
|
||||
Assert.AreEqual("Fahrrad bereits reserviert durch anderen Nutzer.", l_oViewModel.StateText);
|
||||
Assert.AreEqual(Color.Red, l_oViewModel.StateColor);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_BookedBySomeoneElse()
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable("2", false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, "Test description", "3");
|
||||
|
||||
l_oBike.State.Load(
|
||||
InUseStateEnum.Booked,
|
||||
new DateTime(2017, 10, 24, 21, 49, 3),
|
||||
"ragu@gnu-systems.de",
|
||||
"4asdfA");
|
||||
|
||||
var l_oStoreMock = new StoreMock(new Account("john@long", "123456789" /* password */, "987654321" /* session cookie */, new List<string> { "TINK" }));
|
||||
|
||||
var l_oViewModel = new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
l_oBike,
|
||||
new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789"),
|
||||
new BikeAtStationInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>());
|
||||
|
||||
Assert.AreEqual("Test description", l_oViewModel.Name);
|
||||
Assert.AreEqual("2", l_oViewModel.DisplayId);
|
||||
Assert.AreEqual("2", l_oViewModel.Id);
|
||||
Assert.AreEqual("Fahrrad bereits gebucht durch anderen Nutzer.", l_oViewModel.StateText);
|
||||
Assert.AreEqual(Color.Red, l_oViewModel.StateColor);
|
||||
}
|
||||
}
|
||||
}
|
144
TestTINKLib/Fixtures/ObjectTests/ViewModel/TestBikeViewModel.cs
Normal file
144
TestTINKLib/Fixtures/ObjectTests/ViewModel/TestBikeViewModel.cs
Normal file
|
@ -0,0 +1,144 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.User;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.ViewModel;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
using TINK.Model.State;
|
||||
using System.Collections.Generic;
|
||||
using TINK.Repository;
|
||||
using TINK.ViewModel.Bikes.Bike;
|
||||
|
||||
namespace UITest.Fixtures.ViewModel
|
||||
{
|
||||
public class TestBikeViewModel
|
||||
{
|
||||
private class BikeInfoMutable : TINK.Model.Bike.BC.BikeInfoMutable
|
||||
{
|
||||
public BikeInfoMutable(
|
||||
string p_iId,
|
||||
bool p_bIsDemo = false,
|
||||
IEnumerable<string> p_oGroup = null,
|
||||
WheelType? p_eWheelType = null,
|
||||
TypeOfBike? p_eTypeOfBike = null,
|
||||
string description = null,
|
||||
string p_strCurrentStationName = null,
|
||||
Uri operatorUri = null,
|
||||
Func<DateTime> p_oDateTimeProvider = null,
|
||||
IStateInfo stateInfo = null) : base(p_iId, p_bIsDemo, p_oGroup, p_eWheelType, p_eTypeOfBike, description, p_strCurrentStationName, operatorUri, null, p_oDateTimeProvider, stateInfo)
|
||||
{
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
public static BikeViewModelBase TestStateText_LoggedIn_Reserved(Func<TINK.Model.Bike.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable(
|
||||
"2",
|
||||
false,
|
||||
new List<string> { "TINK" },
|
||||
WheelType.Trike,
|
||||
TypeOfBike.Cargo,
|
||||
"Test description",
|
||||
"3",
|
||||
null,
|
||||
() => new DateTime(1980, 1, 1)); // Now time stamp
|
||||
|
||||
// Update state from Copri.
|
||||
l_oBike.State.Load(
|
||||
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
|
||||
new DateTime(1980, 1, 1), // Date when bike was booked.
|
||||
"ragu@gnu-systems.de"); // Owner from Copri.
|
||||
|
||||
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, "987654321" /* session cookie */, new List<string> { "TINK" }));
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789");
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oBike.State.Value);
|
||||
Assert.IsTrue(l_oUser.IsLoggedIn);
|
||||
Assert.AreEqual(l_oBike.State.MailAddress, l_oUser.Mail);
|
||||
|
||||
// Do not update from Copri
|
||||
var l_oViewModel = p_oFactory(l_oBike, l_oUser);
|
||||
|
||||
return l_oViewModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
public static BikeViewModelBase TestStateText_LoggedIn_ReservedWithCopriConnect(Func<TINK.Model.Bike.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable(
|
||||
"2",
|
||||
false,
|
||||
new List<string> { "TINK" },
|
||||
WheelType.Trike,
|
||||
TypeOfBike.Cargo,
|
||||
"Test description",
|
||||
"3",
|
||||
null,
|
||||
() => (new DateTime(1980, 1, 1)).Add(new TimeSpan(0, 8, 0)));
|
||||
|
||||
// Update state from Copri.
|
||||
l_oBike.State.Load(
|
||||
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
|
||||
new DateTime(1980, 1, 1),
|
||||
"ragu@gnu-systems.de", // Owner from Copri.
|
||||
"4asdfA"); // Reservation code from Copri
|
||||
|
||||
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, "987654321" /* session cookie */, new List<string> { "TINK" }));
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock, // Mocks account store functionality.
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789");
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oBike.State.Value);
|
||||
Assert.IsTrue(l_oUser.IsLoggedIn);
|
||||
Assert.AreEqual(l_oBike.State.MailAddress, l_oUser.Mail);
|
||||
|
||||
var l_oViewModel = p_oFactory(l_oBike, l_oUser); // Bikes collection mock.
|
||||
|
||||
return l_oViewModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
public static BikeViewModelBase TestStateText_LoggedIn_Booked(Func<TINK.Model.Bike.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
|
||||
{
|
||||
var l_oBike = new BikeInfoMutable("2", false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, "Test description", "3");
|
||||
|
||||
// Update from Copri.
|
||||
l_oBike.State.Load(
|
||||
InUseStateEnum.Booked,
|
||||
new DateTime(2017, 10, 24, 21, 49, 3),
|
||||
"ragu@gnu-systems.de",
|
||||
"4asdfA");
|
||||
|
||||
var l_oCopriServer = new CopriCallsMemory(SampleSets.Set1, 1);
|
||||
|
||||
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, "987654321" /* session cookie */, new List<string> { "TINK" }));
|
||||
var l_oUser = new User(
|
||||
l_oStoreMock,
|
||||
l_oStoreMock.Load().Result,
|
||||
"123456789"); // Device id
|
||||
|
||||
// Verify prerequisites
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oBike.State.Value);
|
||||
Assert.IsTrue(l_oUser.IsLoggedIn);
|
||||
Assert.AreEqual(l_oBike.State.MailAddress, l_oUser.Mail);
|
||||
|
||||
var l_oViewModel = p_oFactory(l_oBike, l_oUser);
|
||||
|
||||
return l_oViewModel;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using TestTINKLib.Mocks.Services;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.User;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Bikes.Bike;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBikeViewModelFactory
|
||||
{
|
||||
[Test]
|
||||
public void TestCreate()
|
||||
{
|
||||
Assert.AreEqual(
|
||||
typeof(TINK.ViewModel.Bikes.Bike.BC.BikeViewModel),
|
||||
BikeViewModelFactory.Create(
|
||||
() => false, // Is connected delegate,
|
||||
(isconnected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // lock service
|
||||
(index) => { }, // bikeRemoveDelegate
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null, // viewService
|
||||
new TINK.Model.Bike.BC.BikeInfoMutable(new TINK.Model.Bike.BluetoothLock.BikeInfo("42", 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "42")),
|
||||
MockRepository.GenerateStub<IUser>(), // user
|
||||
MockRepository.GenerateStub<IInUseStateInfoProvider>(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()).GetType()); // stateInfoProvider
|
||||
|
||||
Assert.AreEqual(
|
||||
typeof(TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel),
|
||||
BikeViewModelFactory.Create(
|
||||
() => false, // Is connected delegate,
|
||||
(isconnected) => null, // connectorFactory
|
||||
new GeolocationMock(), // geolocation
|
||||
new LocksServiceMock(), // lock service
|
||||
(index) => { }, // bikeRemoveDelegate
|
||||
null, // viewUpdateManager
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null, // viewService
|
||||
new TINK.Model.Bike.BluetoothLock.BikeInfoMutable(new TINK.Model.Bike.BluetoothLock.BikeInfo("42", 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "42")),
|
||||
MockRepository.GenerateStub<IUser>(), // user
|
||||
MockRepository.GenerateStub<IInUseStateInfoProvider>(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()).GetType()); // stateInfoProvider
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,31 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.ViewModel;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestMyBikeInUseStateInfoProvider
|
||||
{
|
||||
[Test]
|
||||
public void TestGetReservedInfo()
|
||||
{
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null), Is.EqualTo("Max. reservation time of 15 minutes expired."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, code: "Code12"), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, "12"), Is.EqualTo("Location 12, max. reservation time of 15 minutes expired."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, "12", "Code12"), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(10)), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(10), "123"), Is.EqualTo("Location Station 123, still 0 minutes reserved."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(10), "123", "code123"), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetBookedInfoInfo()
|
||||
{
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetBookedInfo(null), Is.EqualTo("Bike is rented."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetBookedInfo(DateTime.Now, "123", "Code123"), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetBookedInfo(DateTime.Now, code: "Code123"), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetBookedInfo(DateTime.Parse("2020-12-19 0:22"), "123"), Is.EqualTo("Rented since 19. December 00:22."));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using System;
|
||||
using TINK.Model.Device;
|
||||
using TINK.ViewModel;
|
||||
using TINK.ViewModel.Bikes;
|
||||
|
||||
namespace UITest.Fixtures.ViewModel
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestMyBikesPageViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Reserved()
|
||||
{
|
||||
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Reserved(
|
||||
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
bike,
|
||||
user,
|
||||
new MyBikeInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()));
|
||||
|
||||
|
||||
Assert.AreEqual("Location Station 3, still 15 minutes reserved.", l_oViewModel.StateText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_ReservedWithCopriConnect()
|
||||
{
|
||||
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_ReservedWithCopriConnect(
|
||||
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
bike,
|
||||
user,
|
||||
new MyBikeInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()));
|
||||
|
||||
Assert.AreEqual("Code 4asdfA, location Station 3, still 7 minutes reserved.", l_oViewModel.StateText);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// </summary>
|
||||
///
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Booked()
|
||||
{
|
||||
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Booked(
|
||||
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
NSubstitute.Substitute.For<ISmartDevice>(),
|
||||
null,
|
||||
bike,
|
||||
user,
|
||||
new MyBikeInUseStateInfoProvider(),
|
||||
MockRepository.GenerateStub<IBikesViewModel>()));
|
||||
|
||||
Assert.AreEqual(
|
||||
$"Code 4asdfA, location Station 3, rented since {new DateTime(2018, 10, 24, 21, 49, 00).ToString("dd. MMMM HH:mm")}.",
|
||||
l_oViewModel.StateText);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,788 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TestTINKLib.Mocks.Connector;
|
||||
using TestTINKLib.Mocks.Device;
|
||||
using TestTINKLib.Mocks.Services;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.View;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
using TINK.ViewModel.Map;
|
||||
using TINK.ViewModel.Settings;
|
||||
using Plugin.Permissions.Abstractions;
|
||||
using Plugin.BLE.Abstractions.Contracts;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using NSubstitute;
|
||||
using TINK.Services.BluetoothLock.Tdo;
|
||||
using TINK.ViewModel.MyBikes;
|
||||
using Plugin.Permissions;
|
||||
using Xamarin.Forms;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using NSubstitute.ExceptionExtensions;
|
||||
using TINK.Services;
|
||||
using TINK.Model.Device;
|
||||
|
||||
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestMyBikesPageViewModel
|
||||
{
|
||||
[Test]
|
||||
public async Task TestConstruct_Droid()
|
||||
{
|
||||
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
// Fake location permissions to be set
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>().Returns(Task.FromResult(PermissionStatus.Granted));
|
||||
geolocation.Active.IsGeolcationEnabled.Returns(true); // Fake gps to be on
|
||||
bluetooth.State.Returns(BluetoothState.On); // Fake bluetooth to be on
|
||||
|
||||
// Fake bluetooth answer for locks with id 2200545 and 2200537.
|
||||
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(
|
||||
new List<LockInfoTdo> {
|
||||
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
|
||||
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
|
||||
}
|
||||
);
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" } )),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
|
||||
geolocation,
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions, /* permissions */
|
||||
bluetooth, /* bluetooth */
|
||||
Device.Android,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
geolocation.Active, // geolocation
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>();
|
||||
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
|
||||
var btDummy = bluetooth.Received().State;
|
||||
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>());
|
||||
});
|
||||
|
||||
Assert.IsEmpty(myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
Assert.AreEqual("Rented since 06. November 17:53.", bike1545.StateText);
|
||||
Assert.AreEqual("Rented since 12. October 08:38.", bike1537.StateText);
|
||||
Assert.AreEqual("Close lock", bike1545.LockitButtonText);
|
||||
Assert.AreEqual("Open lock & continue renting", bike1537.LockitButtonText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_Droid_NoPermissions_OpenSettings()
|
||||
{
|
||||
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
// Fake location permissions not to be set
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>().Returns(Task.FromResult(PermissionStatus.Denied));
|
||||
|
||||
// Fake anwser on question whether to open permissions dialog
|
||||
viewService.DisplayAlert(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>()).Returns(true);
|
||||
|
||||
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(
|
||||
new List<LockInfoTdo> {
|
||||
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
|
||||
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
|
||||
}
|
||||
);
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
|
||||
geolocation,
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions, /* permissions */
|
||||
bluetooth, /* bluetooth */
|
||||
Device.Android,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
geolocation.Active, // geolocation
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>();
|
||||
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
|
||||
permissions.RequestPermissionAsync<LocationPermission>(); // Ask user from permissions.
|
||||
viewService.DisplayAlert(
|
||||
"Hint",
|
||||
"Please allow location sharing so that bike lock/locks can be managed.\r\nOpen sharing dialog?",
|
||||
"Yes",
|
||||
"No");
|
||||
permissions.OpenAppSettings();
|
||||
});
|
||||
|
||||
Assert.IsEmpty(myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
Assert.AreEqual("Rented since 06. November 17:53.", bike1545.StateText);
|
||||
Assert.AreEqual("Rented since 12. October 08:38.", bike1537.StateText);
|
||||
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
|
||||
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_Droid_NoPermissions()
|
||||
{
|
||||
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
// Fake location permissions not to be set
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>().Returns(Task.FromResult(PermissionStatus.Denied));
|
||||
|
||||
permissions.OpenAppSettings().Throws<Exception>(); // Ensures that method is not called and fixture succeeds.
|
||||
|
||||
// Fake anwser on question whether to open permissions dialog
|
||||
viewService.DisplayAlert(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>()).Returns(false);
|
||||
|
||||
// Fake bluetooth answer for locks with id 2200545 and 2200537.
|
||||
var lockInfoTdo = new List<LockInfoTdo> {
|
||||
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
|
||||
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
|
||||
};
|
||||
|
||||
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(lockInfoTdo);
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
|
||||
geolocation,
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions, /* permissions */
|
||||
bluetooth, /* bluetooth */
|
||||
Device.Android,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
geolocation.Active, // geolocation
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>();
|
||||
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
|
||||
permissions.RequestPermissionAsync<LocationPermission>(); // Ask user from permissions.
|
||||
viewService.DisplayAlert(
|
||||
"Hint",
|
||||
"Please allow location sharing so that bike lock/locks can be managed.\r\nOpen sharing dialog?",
|
||||
"Yes",
|
||||
"No");
|
||||
});
|
||||
|
||||
Assert.IsEmpty(myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
Assert.AreEqual("Rented since 06. November 17:53.", bike1545.StateText);
|
||||
Assert.AreEqual("Rented since 12. October 08:38.", bike1537.StateText);
|
||||
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
|
||||
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_Droid_GeolocationOff()
|
||||
{
|
||||
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
// Fake location permissions to be set
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>().Returns(Task.FromResult(PermissionStatus.Granted));
|
||||
geolocation.Active.IsGeolcationEnabled.Returns(false); // Fake gps to be off
|
||||
|
||||
// Fake bluetooth answer for locks with id 2200545 and 2200537.
|
||||
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(
|
||||
new List<LockInfoTdo> {
|
||||
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
|
||||
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
|
||||
}
|
||||
);
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
|
||||
geolocation,
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions, /* permissions */
|
||||
bluetooth, /* bluetooth */
|
||||
Device.Android,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
geolocation.Active, // geolocation
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>();
|
||||
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
|
||||
viewService.DisplayAlert(
|
||||
"Hint",
|
||||
"Please activate location so that bike lock can be found!",
|
||||
"OK");
|
||||
});
|
||||
|
||||
Assert.IsEmpty(myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
Assert.AreEqual("Rented since 06. November 17:53.", bike1545.StateText);
|
||||
Assert.AreEqual("Rented since 12. October 08:38.", bike1537.StateText);
|
||||
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
|
||||
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_Droid_BluetoothOff()
|
||||
{
|
||||
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
// Fake location permissions to be set
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>().Returns(Task.FromResult(PermissionStatus.Granted));
|
||||
geolocation.Active.IsGeolcationEnabled.Returns(true); // Fake gps to be on
|
||||
bluetooth.State.Returns(BluetoothState.Off); // Fake bluetooth to be off
|
||||
|
||||
var lockInfoTdo = new List<LockInfoTdo> {
|
||||
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
|
||||
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
|
||||
};
|
||||
|
||||
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(lockInfoTdo);
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
|
||||
geolocation,
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions, /* permissions */
|
||||
bluetooth, /* bluetooth */
|
||||
Device.Android,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
geolocation.Active, // geolocation
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
// Verify behaviour
|
||||
Received.InOrder(() =>
|
||||
{
|
||||
permissions.CheckPermissionStatusAsync<LocationPermission>();
|
||||
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
|
||||
var btDummy = bluetooth.Received().State;
|
||||
viewService.DisplayAlert(
|
||||
"Hint",
|
||||
"Please enable Bluetooth to manage bike lock/locks.",
|
||||
"OK");
|
||||
});
|
||||
|
||||
Assert.IsEmpty(myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
|
||||
Assert.AreEqual("Rented since 06. November 17:53.", bike1545.StateText);
|
||||
Assert.AreEqual("Rented since 12. October 08:38.", bike1537.StateText);
|
||||
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
|
||||
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_NoBikesOccupied()
|
||||
{
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "Invalid_SessionCookie", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions,
|
||||
bluetooth,
|
||||
Device.iOS,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
new GeolocationMock(),
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
Assert.IsTrue(new List<string> { "Updating...", string.Empty }.Contains(myBikes.StatusInfoText));
|
||||
|
||||
Assert.AreEqual(0, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsFalse(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
Assert.IsTrue(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.AreEqual("Momentan sind keine Fahrräder auf Benutzer a@b reserviert/ gebucht.", myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestConstruct_Offline()
|
||||
{
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => false, // Offline
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions,
|
||||
bluetooth,
|
||||
Device.iOS,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
new GeolocationMock(),
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService);
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Offline.", myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
Assert.AreEqual("Code 2931, location Station 4, rented since 28. November 13:06.", myBikes.FirstOrDefault(x => x.Id == "7").StateText);
|
||||
Assert.AreEqual("Code 3630, location Station 5, rented since 28. November 11:01.", myBikes.FirstOrDefault(x => x.Id == "8").StateText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.AreEqual(string.Empty, myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestTinkApp_WebConnectCommunicationError()
|
||||
{
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
|
||||
uri,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default automated test envirnoment",
|
||||
sessionCookie,
|
||||
mail,
|
||||
server: new CopriProviderHttps(
|
||||
uri,
|
||||
TinkApp.MerchantId,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default automated test envirnoment",
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory(sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new WebConnectFailureException(msg, new Exception("Source expection."))))),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => false, // Offline
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions,
|
||||
bluetooth,
|
||||
Device.iOS,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
new GeolocationMock(),
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService)
|
||||
{
|
||||
IsReportLevelVerbose = true
|
||||
};
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Connection interrupted, server unreachable.", myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
Assert.AreEqual("Code 2931, location Station 4, rented since 28. November 13:06.", myBikes.FirstOrDefault(x => x.Id == "7").StateText);
|
||||
Assert.AreEqual("Code 3630, location Station 5, rented since 28. November 11:01.", myBikes.FirstOrDefault(x => x.Id == "8").StateText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.AreEqual(string.Empty, myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestTinkApp_GeneralPurposeError()
|
||||
{
|
||||
var locksService = Substitute.For<ILocksService>();
|
||||
var timeOut = Substitute.For<ITimeOutProvider>();
|
||||
var viewService = Substitute.For<IViewService>();
|
||||
var permissions = Substitute.For<IPermissions>();
|
||||
var bluetooth = Substitute.For<IBluetoothLE>();
|
||||
|
||||
locksService.TimeOut.Returns(timeOut);
|
||||
timeOut.MultiConnect.Returns(new TimeSpan(0));
|
||||
|
||||
var tinkApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
|
||||
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
|
||||
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
|
||||
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
|
||||
Serilog.Events.LogEventLevel.Error,
|
||||
activeLockService: locksService.GetType().FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
|
||||
uri,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie,
|
||||
mail,
|
||||
server: new CopriProviderHttps(
|
||||
uri,
|
||||
TinkApp.MerchantId,
|
||||
"TestTINKApp/3.0.127 AutomatedTestEnvirnoment/Default",
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory(sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new Exception(msg)))),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
locksService,
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
permissions,
|
||||
isConnectedFunc: () => false, // Offline
|
||||
postAction: (d, obj) => d(obj),
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
|
||||
whatsNewShownInVersion: null); // Whats new page was never shown.
|
||||
|
||||
var myBikes = new MyBikesPageViewModel(
|
||||
tinkApp.ActiveUser,
|
||||
permissions,
|
||||
bluetooth,
|
||||
Device.iOS,
|
||||
() => tinkApp.GetIsConnected(),
|
||||
(isConnected) => tinkApp.GetConnector(isConnected),
|
||||
new GeolocationMock(),
|
||||
locksService,
|
||||
tinkApp.Polling,
|
||||
(d, obj) => d(obj),
|
||||
Substitute.For<ISmartDevice>(),
|
||||
viewService)
|
||||
{
|
||||
IsReportLevelVerbose = true
|
||||
};
|
||||
|
||||
await myBikes.OnAppearing();
|
||||
|
||||
Assert.AreEqual("Connection interrupted.", myBikes.StatusInfoText);
|
||||
|
||||
Assert.AreEqual(2, myBikes.Count);
|
||||
Assert.IsTrue(myBikes.IsIdle);
|
||||
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
|
||||
|
||||
Assert.AreEqual("Code 2931, location Station 4, rented since 28. November 13:06.", myBikes.FirstOrDefault(x => x.Id == "7").StateText);
|
||||
Assert.AreEqual("Code 3630, location Station 5, rented since 28. November 11:01.", myBikes.FirstOrDefault(x => x.Id == "8").StateText);
|
||||
|
||||
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
|
||||
Assert.AreEqual(string.Empty, myBikes.NoBikesOccupiedText);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
using NUnit.Framework;
|
||||
using Rhino.Mocks;
|
||||
using TINK.Model.Bike;
|
||||
using TINK.Model.Bikes.Bike.BC;
|
||||
using TINK.ViewModel;
|
||||
namespace UITest.Fixtures.ObjectTests.ViewModel
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
public class TestViewModelHelper
|
||||
{
|
||||
[Test]
|
||||
public void TestGetDisplayName_DefinedTypes()
|
||||
{
|
||||
var l_oBike = MockRepository.GenerateStub<IBikeInfoMutable>();
|
||||
l_oBike.Stub(x => x.WheelType).Return(WheelType.Two);
|
||||
l_oBike.Stub(x => x.TypeOfBike).Return(TypeOfBike.Citybike);
|
||||
l_oBike.Stub(x => x.Description).Return("MeinStadtrad");
|
||||
l_oBike.Stub(x => x.Id).Return("22");
|
||||
Assert.AreEqual(
|
||||
"MeinStadtrad",
|
||||
l_oBike.GetDisplayName());
|
||||
|
||||
Assert.AreEqual(
|
||||
"22",
|
||||
l_oBike.GetDisplayId());
|
||||
|
||||
l_oBike = MockRepository.GenerateStub<IBikeInfoMutable>();
|
||||
l_oBike.Stub(x => x.WheelType).Return(WheelType.Two);
|
||||
l_oBike.Stub(x => x.TypeOfBike).Return(TypeOfBike.Citybike);
|
||||
l_oBike.Stub(x => x.Id).Return("22");
|
||||
l_oBike.Stub(x => x.IsDemo).Return(true);
|
||||
l_oBike.Stub(x => x.Description).Return("MeinStadtrad");
|
||||
Assert.AreEqual(
|
||||
"MeinStadtrad",
|
||||
l_oBike.GetDisplayName());
|
||||
Assert.AreEqual(
|
||||
"22",
|
||||
l_oBike.GetDisplayId());
|
||||
|
||||
l_oBike = MockRepository.GenerateStub<IBikeInfoMutable>();
|
||||
l_oBike.Stub(x => x.WheelType).Return(WheelType.Trike);
|
||||
l_oBike.Stub(x => x.TypeOfBike).Return(TypeOfBike.Cargo);
|
||||
l_oBike.Stub(x => x.Description).Return("MeinCargoDreiradl");
|
||||
l_oBike.Stub(x => x.Id).Return("22");
|
||||
Assert.AreEqual(
|
||||
"MeinCargoDreiradl",
|
||||
l_oBike.GetDisplayName());
|
||||
Assert.AreEqual(
|
||||
"22",
|
||||
l_oBike.GetDisplayId());
|
||||
|
||||
l_oBike = MockRepository.GenerateStub<IBikeInfoMutable>();
|
||||
l_oBike.Stub(x => x.WheelType).Return(WheelType.Two);
|
||||
l_oBike.Stub(x => x.TypeOfBike).Return(TypeOfBike.Cargo);
|
||||
l_oBike.Stub(x => x.Description).Return("MeinCargoALololong");
|
||||
l_oBike.Stub(x => x.Id).Return("22");
|
||||
Assert.AreEqual(
|
||||
"MeinCargoALololong",
|
||||
l_oBike.GetDisplayName());
|
||||
Assert.AreEqual(
|
||||
"22",
|
||||
l_oBike.GetDisplayId());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetDisplayName_UndefinedTypes()
|
||||
{
|
||||
var l_oBike = MockRepository.GenerateStub<IBikeInfoMutable>();
|
||||
l_oBike.Stub(x => x.WheelType).Return(WheelType.Mono);
|
||||
l_oBike.Stub(x => x.TypeOfBike).Return(TypeOfBike.Cargo);
|
||||
l_oBike.Stub(x => x.Description).Return("SuperCargo");
|
||||
l_oBike.Stub(x => x.Id).Return("22");
|
||||
Assert.AreEqual(
|
||||
"SuperCargo",
|
||||
l_oBike.GetDisplayName());
|
||||
|
||||
Assert.AreEqual(
|
||||
"22",
|
||||
l_oBike.GetDisplayId());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using TINK.Model;
|
||||
using TINK.Repository;
|
||||
|
||||
namespace TestTINKLib.Fixtures.UseCases.ConnectedOffline
|
||||
{
|
||||
using NSubstitute;
|
||||
using TestTINKLib.Mocks.Device;
|
||||
using TestTINKLib.Mocks.Services;
|
||||
using TestTINKLib.Model.User.Account;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.Geolocation;
|
||||
using TINK.Services;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
[TestFixture]
|
||||
public class TestTinkApp
|
||||
{
|
||||
[Test, Explicit("Draft")]
|
||||
public void TestConstruct()
|
||||
{
|
||||
var l_oApp = new TinkApp(
|
||||
new TINK.Model.Settings.Settings(
|
||||
activeLockService: typeof(LocksServiceMock).FullName,
|
||||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
(isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(sessionCookie, mail, new CopriCallsMemory(SampleSets.Set2, 1)),
|
||||
Substitute.For<IServicesContainer<IGeolocation>>(),
|
||||
new LocksServiceMock(),
|
||||
new DeviceMock(),
|
||||
new SpecialFolderMock(),
|
||||
null, // Cipher
|
||||
new PermissionsMock(),
|
||||
isConnectedFunc: () => true,
|
||||
currentVersion: new Version(3, 2, 0, 115), // Current app version
|
||||
lastVersion: new Version(3, 0, 173)); // Current app version. Must be larger or equal 3.0.173 to
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue