diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfo.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfo.cs
new file mode 100644
index 0000000..767faa7
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfo.cs
@@ -0,0 +1,20 @@
+using NUnit.Framework;
+using TINK.Model.Bike.BC;
+
+namespace TestTINKLib.Fixtures.ObjectTests.Bike.BC
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ public class TestBikeInfo
+ {
+ [Test]
+ public void TestCtorCopyNull()
+ {
+ Assert.Throws(
+ () => new BikeInfo(null),
+ "Verify that no unspecific reference not set to... exception is thrown");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfoMutable.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfoMutable.cs
new file mode 100644
index 0000000..c163684
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/BC/TestBikeInfoMutable.cs
@@ -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 group = null,
+ WheelType? wheelType = null,
+ TypeOfBike? typeOfBike = null,
+ string description = null,
+ string currentStationId = null,
+ Uri operatorUri = null,
+ TariffDescription tariffDescription = null,
+ Func 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 { "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();
+ var l_oStateInfoMock = MockRepository.GenerateStub();
+
+ 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();
+ l_oStateInfoMock = MockRepository.GenerateStub();
+
+ 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();
+ l_oStateInfoMock = MockRepository.GenerateStub();
+
+ 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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestBikeInfo.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestBikeInfo.cs
new file mode 100644
index 0000000..4f40e11
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestBikeInfo.cs
@@ -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
+ {
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [Test]
+ public void TestCtorCopyNull()
+ {
+ Assert.Throws(
+ () => new BikeInfo(null, null),
+ "Verify that no unspecific reference not set to... exception is thrown");
+
+ Assert.Throws(
+ () => 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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfo.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfo.cs
new file mode 100644
index 0000000..5e83381
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfo.cs
@@ -0,0 +1,155 @@
+using NUnit.Framework;
+using System;
+using TINK.Model.Bike.BluetoothLock;
+namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
+{
+ [TestFixture]
+ public class TestLockInfo
+ {
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [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());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfoHelper.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfoHelper.cs
new file mode 100644
index 0000000..8956633
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfoHelper.cs
@@ -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
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ public class TestLockInfoHelper
+ {
+ [Test]
+ public void TestUpdateById_State()
+ {
+ var locksInfo = new List {
+ 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 {
+ 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 {
+ 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 {
+ 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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfoMutable.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfoMutable.cs
new file mode 100644
index 0000000..2b15d30
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/BluetoothLock/TestLockInfoMutable.cs
@@ -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
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBike.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBike.cs
new file mode 100644
index 0000000..715e962
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBike.cs
@@ -0,0 +1,49 @@
+using NUnit.Framework;
+
+namespace TestTINKLib.Fixtures.ObjectTests.Bike
+{
+ using TINK.Model.Bike;
+
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollection.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollection.cs
new file mode 100644
index 0000000..95a8f78
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollection.cs
@@ -0,0 +1,25 @@
+using NUnit.Framework;
+using System;
+using TINK.Model.Bike;
+
+
+namespace TestTINKLib
+{
+
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ public class TestBikeCollection
+ {
+ /// Tests the member.
+ [Test]
+ public void TestConstruct()
+ {
+ var l_oColl = new BikeCollection();
+
+ Assert.AreEqual(0, l_oColl.Count);
+ Assert.IsNull(l_oColl.GetById(1));
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionFilter.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionFilter.cs
new file mode 100644
index 0000000..f8d90f7
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionFilter.cs
@@ -0,0 +1,78 @@
+using NUnit.Framework;
+using System.Collections.Generic;
+using TINK.Model;
+using TINK.Model.Bike;
+
+namespace TestTINKLib.Fixtures.ObjectTests.Bike
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ public class TestBikeCollectionFilter
+ {
+ [Test]
+ public void TestGetAtStation()
+ {
+ var coll = new BikeCollection(
+ new Dictionary
+ {
+ {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
+ {
+ {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
+ {
+ {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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionMutable.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionMutable.cs
new file mode 100644
index 0000000..a67b6ea
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionMutable.cs
@@ -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
+{
+
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ public class TestBikeCollectionMutable
+ {
+ /// Tests the member.
+ [Test]
+ public void TestAdd()
+ {
+ var l_oColl = new BikeCollectionMutable();
+
+ l_oColl.Add(new BikeInfoMutable(57, false, new List { "TINK" }, WheelType.Two, TypeOfBike.Allround));
+
+ Assert.Throws(() => l_oColl.Add(new BikeInfoMutable(57, false, new List { "TINK" }, WheelType.Trike, TypeOfBike.Cargo)));
+ }
+
+ [Test]
+ public void TestUpdate_Null()
+ {
+ var l_oBikeRequested = new BikeInfoMutable(20, false, new List { "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 { "TINK" }, WheelType.Two, TypeOfBike.Allround),
+ new BikeInfoMutable(57, false, new List { "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 { "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 { "TINK" }, WheelType.Two, TypeOfBike.Allround),
+ new BikeInfoMutable(57, false, new List { "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
+ {
+ 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"));
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionSerializeJSON.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionSerializeJSON.cs
new file mode 100644
index 0000000..b264970
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeCollectionSerializeJSON.cs
@@ -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
+{
+
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [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 { "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(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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeMutable.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeMutable.cs
new file mode 100644
index 0000000..2337035
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeMutable.cs
@@ -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
+{
+
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ class TestBikeMutable
+ {
+ [Test]
+ public void TestConstruct()
+ {
+ var l_oBike = new BikeInfoMutable(
+ 42,
+ false,
+ new List { "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 { "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 { "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 { "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());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeSerializeJSON.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeSerializeJSON.cs
new file mode 100644
index 0000000..bb28029
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikeSerializeJSON.cs
@@ -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
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [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 { "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(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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikesAvailableResponse.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikesAvailableResponse.cs
new file mode 100644
index 0000000..1f52744
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestBikesAvailableResponse.cs
@@ -0,0 +1,69 @@
+using Newtonsoft.Json;
+using NUnit.Framework;
+using TINK.Repository.Response;
+
+namespace TestTINKLib.Fixtures.ObjectTests.Bike
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [TestFixture]
+ public class TestBikesAvailableResponse
+ {
+ [Test]
+ public void TestDeserializeStationEmpty()
+ {
+ // Response for bike 231 is a real world answer.
+ var l_oBikes = JsonConvert.DeserializeObject(@"
+ {
+ ""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(@"
+ {
+ ""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);
+
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Bike/TestStateBookedInfoSerializeJSON.cs b/TestTINKLib/Fixtures/ObjectTests/Bike/TestStateBookedInfoSerializeJSON.cs
new file mode 100644
index 0000000..65a8bbd
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Bike/TestStateBookedInfoSerializeJSON.cs
@@ -0,0 +1,44 @@
+using Newtonsoft.Json;
+using NUnit.Framework;
+using System;
+using TINK.Model.State;
+
+
+namespace TestTINKLib.Fixtures.Bike
+{
+ ///
+ /// Moved to TestShareeLib (.Net Core)
+ ///
+ [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(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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/CopriCallsHttpReference.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/CopriCallsHttpReference.cs
new file mode 100644
index 0000000..f9e67a9
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/CopriCallsHttpReference.cs
@@ -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
+{
+ ///
+ /// Object which manages calls to copri.
+ ///
+ public class CopriCallsHttpsReference
+ {
+ /// Logs user in.
+ /// Host to connect to.
+ /// Id of the merchant.
+ /// Mailaddress of user to log in.
+ /// Password to log in.
+ /// Id specifying user and hardware.
+ /// Response which holds auth cookie
+ 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>(response)?.shareejson;
+#else
+ return null;
+#endif
+ }
+
+ /// Logs user out.
+ /// Host to connect to.
+ /// Id of the merchant.
+ /// Cookie which identifies user.
+ 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>(l_oLogoutResponse)?.shareejson;
+#else
+ return null;
+#endif
+ }
+
+ ///
+ /// Get list of stations from file.
+ ///
+ /// URL of the copri host to connect to.
+ /// Id of the merchant.
+ /// Auto cookie of user if user is logged in.
+ /// List of files.
+ 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>(l_oStationsAllResponse)?.shareejson;
+#else
+ return null;
+#endif
+ }
+
+ ///
+ /// Gets a list of bikes from Copri.
+ ///
+ /// URL of the copri host to connect to.
+ /// Id of the merchant.
+ /// Cookie to authenticate user.
+ /// Response holding list of bikes.
+ 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(response);
+#else
+ return null;
+#endif
+ }
+
+ ///
+ /// Gets a list of bikes reserved/ booked by acctive user from Copri.
+ ///
+ /// Id of the merchant.
+ /// Cookie to authenticate user.
+ /// Response holding list of bikes.
+ 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(l_oBikesOccupiedResponse);
+#else
+ return null;
+#endif
+ }
+
+ ///
+ /// Gets booking request response.
+ ///
+ /// Id of the merchant.
+ /// Id of the bike to book.
+ /// Cookie identifying the user.
+ /// Response on booking request.
+ 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>(l_oBikesAvaialbeResponse)?.shareejson;
+#else
+ return null;
+#endif
+ }
+
+ ///
+ /// Gets canel booking request response.
+ ///
+ /// Id of the merchant.
+ /// Id of the bike to book.
+ /// Cookie of the logged in user.
+ /// Response on cancel booking request.
+ 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>(l_oBikesAvaialbeResponse)?.shareejson;
+#else
+ return null;
+#endif
+ }
+
+ ///
+ /// Gets a list of bikes from Copri.
+ ///
+ /// Cookie to authenticate user.
+ ///
+ 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
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Exception/TestAuthcookieNotDefinedException.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Exception/TestAuthcookieNotDefinedException.cs
new file mode 100644
index 0000000..2df5c89
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Exception/TestAuthcookieNotDefinedException.cs
@@ -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(@"{ ""response_state"" : ""Some inner error description""}"))).Message);
+ }
+
+ [Test]
+ public void TestTestIsAuthcookieNotDefined_False()
+ {
+ var response = JsonConvert.DeserializeObject(@"{ ""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($"{{ \"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($"{{ \"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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Filter/TestIntersectFilter.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Filter/TestIntersectFilter.cs
new file mode 100644
index 0000000..c0caba3
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Filter/TestIntersectFilter.cs
@@ -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 { "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 { "Tonk" });
+
+ Assert.AreEqual(0, filter.DoFilter(new List()).Count());
+ }
+
+ [Test]
+ public void TestDoFilter()
+ {
+ var filter = new IntersectGroupFilter(new List { "Tonk", "Honk" });
+
+ Assert.AreEqual(1, filter.DoFilter(new List { "Tonk", "Klonk" }).Count());
+ Assert.AreEqual("Tonk", filter.DoFilter(new List { "Tonk", "Klonk" }).ToArray()[0]);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Filter/TestNullFilter.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Filter/TestNullFilter.cs
new file mode 100644
index 0000000..ed11091
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Filter/TestNullFilter.cs
@@ -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()).Count());
+ Assert.AreEqual(1, filter.DoFilter(new List { "Hello" }).Count());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestCachedQuery.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestCachedQuery.cs
new file mode 100644
index 0000000..e655b14
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestCachedQuery.cs
@@ -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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(STATIONSALL),
+ new System.Exception("Bang when getting stations..."))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(STATIONSALLEMPTY))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE),
+ new System.Exception("Bang when getting bikes..."))));
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(STATIONSALL))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE))));
+
+ server.Stub(x => x.AddToCache(Arg>.Is.Anything));
+ server.Stub(x => x.AddToCache(Arg>.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();
+
+ server.Stub(x => x.GetBikesAvailable()).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE))));
+
+ server.Stub(x => x.AddToCache(Arg>.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();
+
+ 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.");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestCachedQueryLoggedIn.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestCachedQueryLoggedIn.cs
new file mode 100644
index 0000000..bc716d0
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestCachedQueryLoggedIn.cs
@@ -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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(STATIONSALL),
+ new System.Exception("Bang when getting stations..."))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE))));
+
+ server.Stub(x => x.GetBikesOccupied(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(STATIONSALLEMPTY))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE),
+ new System.Exception("Bang when getting bikes..."))));
+
+ server.Stub(x => x.GetBikesOccupied(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESOCCUPIED))));
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(STATIONSALLEMPTY))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESAVAILABLEEMPTY))));
+
+ server.Stub(x => x.GetBikesOccupied(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESOCCUPIED),
+ new System.Exception("Bang when getting bikes occupied..."))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE))));
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetStations(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(STATIONSALL))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE))));
+
+ server.Stub(x => x.GetBikesOccupied(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESOCCUPIED))));
+
+ server.Stub(x => x.AddToCache(Arg>.Is.Anything));
+ server.Stub(x => x.AddToCache(Arg>.Is.Anything));
+ server.Stub(x => x.AddToCache(Arg>.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();
+
+ server.Stub(x => x.GetBikesAvailable()).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE),
+ new System.Exception("Bang, bikes avail..."))));
+
+ server.Stub(x => x.GetBikesOccupied(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESAVAILABLEEMPTY))));
+
+ server.Stub(x => x.GetBikesOccupied(Arg.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(BIKESOCCUPIED),
+ new System.Exception("Bang, error bikes occupied"))));
+
+ server.Stub(x => x.GetBikesAvailable(Arg.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result(
+ typeof(CopriCallsMonkeyStore),
+ JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetBikesAvailable()).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESAVAILABLE))));
+
+ server.Stub(x => x.GetBikesOccupied()).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESOCCUPIED))));
+
+ server.Stub(x => x.AddToCache(Arg>.Is.Anything));
+ server.Stub(x => x.AddToCache(Arg>.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();
+
+ server.Stub(x => x.GetBikesOccupied()).Return(Task.Run(() => new Result(
+ typeof(CopriCallsHttps),
+ JsonConvert.DeserializeObject(BIKESOCCUPIED))));
+
+ server.Stub(x => x.AddToCache(Arg>.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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQuery.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQuery.cs
new file mode 100644
index 0000000..05dbe8d
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQuery.cs
@@ -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();
+
+ server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(STATIONSALL)));
+ server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(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();
+
+ 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.");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQueryLoggedIn.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQueryLoggedIn.cs
new file mode 100644
index 0000000..69c0046
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Query/TestQueryLoggedIn.cs
@@ -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();
+
+ server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(STATIONSALL)));
+ server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(BIKESAVAILABLE)));
+ server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(BIKESAVAILABLE)));
+ server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(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();
+
+ server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject(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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Request/TestRequestBuilder.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Request/TestRequestBuilder.cs
new file mode 100644
index 0000000..0ca652a
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Request/TestRequestBuilder.cs
@@ -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(() =>
+ 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(() =>
+ new RequestBuilder("123").DoReserve("42"));
+ }
+
+ [Test]
+ public void TestDoCancelReservation()
+ {
+ Assert.Throws(() =>
+ new RequestBuilder("123").DoCancelReservation("42"));
+ }
+
+ [Test]
+ public void TestDoSubmitFeedback()
+ {
+ Assert.Throws(() =>
+ new RequestBuilder("123").DoSubmitFeedback("bike3", "Hi", false));
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Request/TestRequestBuilderLoggedIn.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Request/TestRequestBuilderLoggedIn.cs
new file mode 100644
index 0000000..5f52296
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Request/TestRequestBuilderLoggedIn.cs
@@ -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 (() =>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(() =>
+ new RequestBuilderLoggedIn("123", null).GetBikesAvailable());
+
+ Assert.Throws(() =>
+ 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(() =>
+ new RequestBuilderLoggedIn("123", null).GetBikesOccupied());
+
+ Assert.Throws(() =>
+ 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(() =>
+ new RequestBuilderLoggedIn("123", string.Empty).GetStations());
+
+ Assert.Throws(() =>
+ 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));
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBikesAvailableResponse.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBikesAvailableResponse.cs
new file mode 100644
index 0000000..17fbe3f
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBikesAvailableResponse.cs
@@ -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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBikesOccupiedResponse.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBikesOccupiedResponse.cs
new file mode 100644
index 0000000..9e4996e
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBikesOccupiedResponse.cs
@@ -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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBookingResponse.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBookingResponse.cs
new file mode 100644
index 0000000..3c97274
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestBookingResponse.cs
@@ -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.");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestResponseBase.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestResponseBase.cs
new file mode 100644
index 0000000..1db087c
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestResponseBase.cs
@@ -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(@"
+ {
+ ""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());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestResponseHelper.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestResponseHelper.cs
new file mode 100644
index 0000000..1e6cd0a
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestResponseHelper.cs
@@ -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(@"{ ""response_state"" : ""OK"" }");
+ Assert.NotNull(l_oResponse.GetIsResponseOk(ResponseHelper.BIKES_OCCUPIED_ACTIONTEXT));
+ }
+
+ [Test]
+ public void TestGetIsResponseOk_BikesOccupied_AuthcookieNotDefined()
+ {
+ var l_oResponseBase = JsonConvert.DeserializeObject($"{{ \"response_state\" : \"Failure 1003: authcookie not defined\" }}");
+ Assert.Throws(() => l_oResponseBase.GetIsResponseOk("Get not succeed"));
+ }
+
+
+ [Test]
+ public void TestGetIsResponseOk_NoBikes()
+ {
+ var l_oResponse = JsonConvert.DeserializeObject(
+ @"{ ""response_state"" : ""OK"", " +
+ @"""authcookie"" : ""KeksoiF2kahH"" }");
+
+ Assert.That(() => l_oResponse.GetIsReserveResponseOk("8"), Throws.Exception.TypeOf());
+ }
+
+ [Test]
+ public void TestGetIsResposeOk_Booking_Declined()
+ {
+ var l_oResponse = JsonConvert.DeserializeObject(@"{ ""response_state"" : ""OK: booking_request declined. max count of 8 occupied bikes has been reached"", ""authcookie"" : ""KeksoiF2kahH"" }");
+ Assert.AreEqual(
+ 8,
+ Assert.Throws(() => l_oResponse.GetIsReserveResponseOk("8")).MaxBikesCount);
+ }
+
+ [Test]
+ public void TestGetIsResposeOk_Logout_AutcookieUnknown()
+ {
+ var l_oResponse = JsonConvert.DeserializeObject($"{{ \"response_state\" : \"Failure 1004: authcookie not defined\"}}");
+
+ Assert.Throws(() => l_oResponse.GetIsResponseOk());
+ }
+
+ [Test]
+ public void TestGetIsReturnBikeResponseOk_Error()
+ {
+ var l_oResponse = JsonConvert.DeserializeObject(
+ @"{ ""response_state"" : ""Failure 1234"", " +
+ @"""authcookie"" : ""KeksoiF2kahH"" }");
+
+ Assert.That(
+ () => l_oResponse.GetIsReturnBikeResponseOk("8"),
+ Throws.Exception.TypeOf>());
+ }
+
+ [Test]
+ public void TestGetIsReturnBikeResponseOk_ErrorNotAtStation()
+ {
+ var l_oResponse = JsonConvert.DeserializeObject(
+ @"{ ""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());
+ }
+
+ [Test]
+ public void TestGetIsReturnBikeResponseOk_ErrorNoGPSData()
+ {
+ var l_oResponse = JsonConvert.DeserializeObject(
+ @"{ ""response_state"" : ""Failure 2245: No GPS data, state change forbidden."", " +
+ @"""authcookie"" : ""KeksoiF2kahH"" }");
+
+ Assert.That(() => l_oResponse.GetIsReturnBikeResponseOk("8"), Throws.Exception.TypeOf());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestStationsAllResponse.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestStationsAllResponse.cs
new file mode 100644
index 0000000..d8ff658
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/Response/TestStationsAllResponse.cs
@@ -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);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestCommandLoggedIn.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCommandLoggedIn.cs
new file mode 100644
index 0000000..d1b1a1d
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCommandLoggedIn.cs
@@ -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
+ {
+ /// Verifies, that logout leads to expected call on copri server.
+ [Test]
+ public void TestDoLogout()
+ {
+ var l_oServer = MockRepository.GenerateStub();
+
+ l_oServer.Stub(x => x.DoAuthoutAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject("{ \"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);
+ }
+
+ /// Verifies, that logout leads to expected call on copri server.
+ [Test]
+ public void TestDoLogout_AuthcookieNotDefined()
+ {
+ var l_oServer = MockRepository.GenerateStub();
+
+ l_oServer.Stub(x => x.DoAuthoutAsync()).Throw(new AuthcookieNotDefinedException("Testing action", JsonConvert.DeserializeObject(@"{ ""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);
+ }
+
+ /// Verifies, that logout leads to expected call on copri server.
+ [Test]
+ public void TestDoLogout_Exception()
+ {
+ var l_oServer = MockRepository.GenerateStub();
+
+ 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(() => l_oCmd.DoLogout().Wait());
+
+ l_oServer.AssertWasCalled(x => x.DoAuthoutAsync());
+ Assert.IsNull(l_oEventArgs);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestConnector.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestConnector.cs
new file mode 100644
index 0000000..1bcf0b4
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestConnector.cs
@@ -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
+ {
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestCommandFactory()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ // 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());
+ }
+
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestCommandFactory_LoggedIn()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ 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());
+ }
+
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestQueryFactory_CachedServer()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ 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());
+ }
+
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestQueryFactory_LoggedIn()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ 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());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestConnectorCache.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestConnectorCache.cs
new file mode 100644
index 0000000..51ab920
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestConnectorCache.cs
@@ -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
+ {
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestCommandFactory()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ // 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());
+ }
+
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestCommandFactory_LoggedIn()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ var l_oCommand = new ConnectorCache(
+ "123", // Logged in
+ "a@b",
+ l_oCopri).Command;
+
+ Assert.AreEqual(typeof(CommandLoggedIn), l_oCommand.GetType());
+ }
+
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestQueryFactory_CachedServer()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ var l_oQuery = new ConnectorCache(
+ "",
+ "",
+ l_oCopri).Query;
+
+ Assert.AreEqual(typeof(TINK.Model.Connector.Query), l_oQuery.GetType());
+ }
+
+ ///
+ /// Verifies that factory method returns correcty type depending on session cookie.
+ ///
+ [Test]
+ public void TestQueryFactory_LoggedIn()
+ {
+ var l_oCopri = MockRepository.GenerateStub();
+
+ var l_oQuery = new ConnectorCache(
+ "123",
+ "a@b",
+ l_oCopri).Query;
+
+ Assert.AreEqual(typeof(QueryLoggedIn), l_oQuery.GetType());
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsHttps.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsHttps.cs
new file mode 100644
index 0000000..8b44807
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsHttps.cs
@@ -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 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 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);
+ }
+
+ /// Log out functionality is only for test purposes.
+ [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);
+ }
+ }
+
+ ///
+ /// Log out functionality is only for test purposes.
+ ///
+ [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(
+ () => 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);
+ }
+ }
+
+ ///
+ /// 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.
+ ///
+ [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);
+ }
+ }
+
+ ///
+ /// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
+ ///
+ [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");
+ }
+
+ ///
+ /// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
+ ///
+ [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");
+ }
+
+ ///
+ /// Attention: Behaves different if called with a period smaller 15minutes because bike will alreay be reserved.
+ ///
+ [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);
+ }
+ }
+
+ ///
+ /// Attention: Behaves different if called with a period smaller 15minutes because bike will alreay be reserved.
+ ///
+ [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);
+ }
+ }
+
+ /// Tests the member.
+ /// Timecode is no more verified since COPRI 4.1.
+ [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.");
+ }
+
+ ///
+ /// 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.
+ ///
+ [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"
+ }
+
+ ///
+ /// Tests the member.
+ ///
+ ///
+ /// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
+ ///
+ [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);
+ }
+
+ ///
+ /// Tests the member.
+ ///
+ ///
+ /// From COPRI version v4.1 switched from TINK devel CopriServerUriList.TINK_DEVEL and CopriServerUriList.TINK_LIVE to CopriServerUriList.SHAREE_DEVEL.
+ ///
+ [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.");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsMemory.cs.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsMemory.cs.cs
new file mode 100644
index 0000000..8649ce1
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsMemory.cs.cs
@@ -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.");
+ }
+ }
+ }
+
+ ///
+ /// Test consistency for a single sample set,
+ ///
+ ///
+ private void VerifyBikeIdIsUnique(CopriCallsMemory p_oMemory)
+ {
+ Dictionary l_oChecker = new Dictionary();
+
+ 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);
+ }
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsStatic.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsStatic.cs
new file mode 100644
index 0000000..94a5daa
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriCallsStatic.cs
@@ -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(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(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(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(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.");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriServerUriList.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriServerUriList.cs
new file mode 100644
index 0000000..a06190c
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestCopriServerUriList.cs
@@ -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 { 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(() => new CopriServerUriList(
+ null,
+ new Uri("http://2.3.4.5")));
+ }
+
+ [Test]
+ public void TestConstruct_AryStringString_InvalidList()
+ {
+ Assert.Throws( () => new CopriServerUriList(
+ (new List()).ToArray(),
+ new Uri("http://2.3.4.5")));
+ }
+
+ [Test]
+ public void TestConstruct_AryStringString_InvalidActiveUri()
+ {
+ Assert.Throws(() => new CopriServerUriList(
+ (new List { 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.");
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestFilter.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestFilter.cs
new file mode 100644
index 0000000..e0d446b
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestFilter.cs
@@ -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
+{
+ /// Tests filter object.
+ [TestFixture]
+ public class TestFilter
+ {
+ /// Tests all stations.
+ [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 { "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 { "TINK" }, l_oConnector);
+ l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
+ Assert.AreEqual(8, l_oStations.StationsAll.Count());
+
+ l_oFilter = new FilteredConnector(new List { "Konrad" }, l_oConnector);
+ l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
+ Assert.AreEqual(2, l_oStations.StationsAll.Count());
+
+ l_oFilter = new FilteredConnector(new List { "AGroupNamedNonsensDoesNotExist" }, l_oConnector);
+ l_oStations = l_oFilter.Query.GetBikesAndStationsAsync().Result.Response;
+ Assert.AreEqual(0, l_oStations.StationsAll.Count());
+
+ l_oFilter = new FilteredConnector(new List(), 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.");
+ }
+
+ /// Tests all stations.
+ [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 { "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 { "TINK" }, l_oConnector);
+ l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
+ Assert.AreEqual(11, l_oBikes.Count());
+
+ l_oFilter = new FilteredConnector(new List { "Konrad" }, l_oConnector);
+ l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
+ Assert.AreEqual(1, l_oBikes.Count());
+
+ l_oFilter = new FilteredConnector(new List { "AGroupNamedNonsensDoesNotExist" }, l_oConnector);
+ l_oBikes = l_oFilter.Query.GetBikesAsync().Result.Response;
+ Assert.AreEqual(0, l_oBikes.Count());
+
+ l_oFilter = new FilteredConnector(new List(), 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();
+ l_oMock.Expect(x => x.IsConnected).Return(true) ;
+ Assert.IsTrue(new FilteredConnector(new List(), l_oMock).IsConnected);
+
+ l_oMock = MockRepository.GenerateMock();
+ l_oMock.Expect(x => x.IsConnected).Return(false);
+ Assert.IsFalse(new FilteredConnector(new List(), l_oMock).IsConnected);
+ }
+ }
+}
diff --git a/TestTINKLib/Fixtures/ObjectTests/Connector/TestTextToTypeHelper.cs b/TestTINKLib/Fixtures/ObjectTests/Connector/TestTextToTypeHelper.cs
new file mode 100644
index 0000000..a0cc667
--- /dev/null
+++ b/TestTINKLib/Fixtures/ObjectTests/Connector/TestTextToTypeHelper.cs
@@ -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