/*
* Copyright (c) 2023 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see .
*/
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
using ProtonVPN.Logging.Contracts;
using ProtonVPN.EntityMapping.Contracts;
using ProtonVPN.EntityMapping.Tests.Mocks;
namespace ProtonVPN.EntityMapping.Tests
{
[TestClass]
public class EntityMapperTest
{
private ILogger _logger;
private Lazy> _mappers;
private EntityMapper _entityMapper;
[TestInitialize]
public void Initialize()
{
_logger = Substitute.For();
_mappers = new Lazy>(CreateMappers);
_entityMapper = new EntityMapper(_logger, _mappers);
}
private IEnumerable CreateMappers()
{
yield return new MockOfEntityMapper();
yield return new MockOfEnumMapper();
}
[TestCleanup]
public void Cleanup()
{
_logger = null;
_mappers = null;
_entityMapper = null;
}
[TestMethod]
public void TestMap_Entity()
{
string value = DateTimeOffset.UtcNow.ToString();
MockOfEntityA mockOfEntityA = new() { Value = value.ToString() };
MockOfEntityB result = _entityMapper.Map(mockOfEntityA);
Assert.IsNotNull(result);
Assert.AreEqual(value, result.Value);
}
[TestMethod]
public void TestMap_Entity_Inverse()
{
string value = DateTimeOffset.UtcNow.ToString();
MockOfEntityB mockOfEntityB = new() { Value = value.ToString() };
MockOfEntityA result = _entityMapper.Map(mockOfEntityB);
Assert.IsNotNull(result);
Assert.AreEqual(value, result.Value);
}
[TestMethod]
public void TestMap_WhenMapperDoesNotExist()
{
string value = DateTimeOffset.UtcNow.ToString();
MockOfEntityA mockOfEntityA = new() { Value = value.ToString() };
Assert.Throws(() => _entityMapper.Map(mockOfEntityA));
}
[TestMethod]
public void TestMap_Enum()
{
MockOfEnumA mockOfEnumA = MockOfEnumA.One;
MockOfEnumB result = _entityMapper.Map(mockOfEnumA);
Assert.IsNotNull(result);
Assert.AreEqual(MockOfEnumB.One, result);
}
[TestMethod]
public void TestMap_Enum_Inverse()
{
MockOfEnumB mockOfEnumB = MockOfEnumB.Two;
MockOfEnumA result = _entityMapper.Map(mockOfEnumB);
Assert.IsNotNull(result);
Assert.AreEqual(MockOfEnumA.Two, result);
}
[TestMethod]
[DataRow(MockOfEnumB.Two, MockOfEnumA.Two)]
[DataRow(null, null)]
public void TestMapNullableStruct(MockOfEnumB? expectedResult, MockOfEnumA? mockOfEnumA)
{
MockOfEnumB? result = _entityMapper.MapNullableStruct(mockOfEnumA);
Assert.AreEqual(expectedResult, result);
}
[TestMethod]
[DataRow(MockOfEnumA.One, MockOfEnumB.One)]
[DataRow(null, null)]
public void TestMapNullableStruct_Inverse(MockOfEnumA? expectedResult, MockOfEnumB? mockOfEnumB)
{
MockOfEnumA? result = _entityMapper.MapNullableStruct(mockOfEnumB);
Assert.AreEqual(expectedResult, result);
}
[TestMethod]
public void TestMapNullableStruct_WhenMapperDoesNotExist()
{
MockOfEnumA mockOfEnumA = MockOfEnumA.One;
Assert.Throws(() => _entityMapper.Map(mockOfEnumA));
}
[TestMethod]
public void TestMap_ListOfEntities()
{
List mockOfAEntities = GenerateEntities(
(int i) => new() { Value = DateTimeOffset.UtcNow.AddDays(i).ToString() });
List result = _entityMapper.Map(mockOfAEntities.ToList());
AssertListsAreEqual(mockOfAEntities, result,
(MockOfEntityA mockOfEntityA, MockOfEntityB mockOfEntityB) => mockOfEntityA.Value == mockOfEntityB.Value);
}
private List GenerateEntities(Func generator)
{
List entities = new();
for (int i = 0; i < 9; i++)
{
entities.Add(generator(i));
}
return entities;
}
private void AssertListsAreEqual(List expectedResult, List result, Func comparer)
{
Assert.IsNotNull(result);
Assert.HasCount(expectedResult.Count, result);
for (int i = 0; i < expectedResult.Count; i++)
{
Assert.IsTrue(comparer(expectedResult[i], result[i]));
}
}
[TestMethod]
public void TestMap_ListOfEntities_Inverse()
{
List mockOfBEntities = GenerateEntities(
(int i) => new() { Value = DateTimeOffset.UtcNow.AddDays(i).ToString() });
List result = _entityMapper.Map(mockOfBEntities.ToList());
AssertListsAreEqual(mockOfBEntities, result,
(MockOfEntityB mockOfEntityB, MockOfEntityA mockOfEntityA) => mockOfEntityB.Value == mockOfEntityA.Value);
}
[TestMethod]
public void TestMap_List_WhenMapperDoesNotExist()
{
List mockOfAEntities = GenerateEntities(
(int i) => new() { Value = DateTimeOffset.UtcNow.AddDays(i).ToString() });
Assert.Throws(() => _entityMapper.Map(mockOfAEntities.ToList()));
}
[TestMethod]
public void TestMap_ListOfEnums()
{
List mockOfAEnums = GenerateEnums((int i) => (MockOfEnumA)i);
List result = _entityMapper.Map(mockOfAEnums.ToList());
AssertListsAreEqual(mockOfAEnums, result,
(MockOfEnumA mockOfEnumA, MockOfEnumB mockOfEnumB) => (int)mockOfEnumA == (int)mockOfEnumB);
}
private List GenerateEnums(Func generator)
{
List entities = new();
for (int i = 0; i < 3; i++)
{
entities.Add(generator(i));
}
return entities;
}
[TestMethod]
public void TestMap_ListOfEnums_Inverse()
{
List mockOfBEnums = GenerateEnums((int i) => (MockOfEnumB)i);
List result = _entityMapper.Map(mockOfBEnums.ToList());
AssertListsAreEqual(mockOfBEnums, result,
(MockOfEnumB mockOfEnumB, MockOfEnumA mockOfEnumA) => (int)mockOfEnumB == (int)mockOfEnumA);
}
}
}