Backend/e-suite.Database.Core/e-suite.Database.Core.UnitTests/DeltaUnitTests.cs
2026-01-20 21:50:10 +00:00

200 lines
7.5 KiB
C#

using NUnit.Framework;
using e_suite.Database.Core.Helpers;
using Microsoft.EntityFrameworkCore;
using Moq;
namespace e_suite.Database.Core.UnitTests;
[TestFixture]
public class DeltaUnitTests
{
private static DbSet<T> GetQueryableMockDbSet<T>(List<T> sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var dbSet = new Mock<DbSet<T>>();
dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>((s) => sourceList.Add(s));
dbSet.Setup(d => d.RemoveRange(It.IsAny<IEnumerable<T>>())).Callback<IEnumerable<T>>(
items =>
{
foreach (var item in items)
{
sourceList.Remove(item);
}
});
dbSet.Setup(d => d.AddRangeAsync(It.IsAny<IEnumerable<T>>(), It.IsAny<CancellationToken>())).Callback<IEnumerable<T>, CancellationToken>(
(items, cancellationToken) =>
{
foreach (var item in items)
{
cancellationToken.ThrowIfCancellationRequested();
sourceList.Add(item);
}
});
return dbSet.Object;
}
private static void AssertListContents(IReadOnlyList<string> listToTest, List<string> list)
{
foreach (var item in list)
Assert.That(listToTest.Contains(item), Is.True);
}
private static void AssertDeltaMatches(IReadOnlyList<DeltaMatch<string>> actualResultMatches, List<string> list)
{
foreach (var item in actualResultMatches)
{
var originalIndex = list.IndexOf(item.Original);
var updatedIndex = list.IndexOf(item.Updated);
Assert.That(originalIndex, Is.GreaterThan(-1));
Assert.That(updatedIndex, Is.GreaterThan(-1));
Assert.That(originalIndex, Is.EqualTo(updatedIndex));
}
}
[Test]
public void CalculateDelta_CalculatesAdditions()
{
//Arrange
var originalList = new List<string>();
var updatedList = new List<string> { "a", "b", "c" };
//Act
var actualResult = Delta<string>.CalculateDelta(updatedList, originalList, StringComparer.InvariantCultureIgnoreCase );
//Assert
Assert.That(actualResult.Additions.Count, Is.EqualTo(3));
AssertListContents(actualResult.Additions, ["a", "b", "c"]);
Assert.That(actualResult.Deletions.Count, Is.EqualTo(0));
Assert.That(actualResult.Matches.Count, Is.EqualTo(0));
}
[Test]
public void CalculateDelta_CalculatesDeletions()
{
//Arrange
var originalList = new List<string> { "d", "e", "f" };
var updatedList = new List<string>();
//Act
var actualResult = Delta<string>.CalculateDelta(updatedList, originalList, StringComparer.InvariantCultureIgnoreCase);
//Assert
Assert.That(actualResult.Additions.Count, Is.EqualTo(0));
Assert.That(actualResult.Deletions.Count, Is.EqualTo(3));
AssertListContents(actualResult.Deletions, ["d", "e", "f"]);
Assert.That(actualResult.Matches.Count, Is.EqualTo(0));
}
[Test]
public void CalculateDelta_CalculatesMatches()
{
//Arrange
var originalList = new List<string> { "g", "h", "i" };
var updatedList = new List<string> { "g", "h", "i" };
//Act
var actualResult = Delta<string>.CalculateDelta(updatedList, originalList, StringComparer.InvariantCultureIgnoreCase);
//Assert
Assert.That(actualResult.Additions.Count, Is.EqualTo(0));
Assert.That(actualResult.Deletions.Count, Is.EqualTo(0));
Assert.That(actualResult.Matches.Count, Is.EqualTo(3));
AssertDeltaMatches(actualResult.Matches, ["g", "h", "i"]);
}
[Test]
public void CalculateDelta_CanCalulateACombinationOfAddDeleteAndMatch()
{
//Arrange
var originalList = new List<string> { "j", "k", "l", "p", "q", "r" };
var updatedList = new List<string> { "m", "n", "o", "p", "q", "r" };
//Act
var actualResult = Delta<string>.CalculateDelta(updatedList, originalList, StringComparer.InvariantCultureIgnoreCase);
//Assert
Assert.That(actualResult.Additions.Count, Is.EqualTo(3));
AssertListContents(actualResult.Additions, ["m", "n", "o"]);
Assert.That(actualResult.Deletions.Count, Is.EqualTo(3));
AssertListContents(actualResult.Deletions, ["j", "k", "l"]);
Assert.That(actualResult.Matches.Count, Is.EqualTo(3));
AssertDeltaMatches(actualResult.Matches, ["p", "q", "r"]);
}
[Test]
public void CalculateDelta_CancellationTokenThrowsExceptionWhenCancelled()
{
//Arrange
var originalList = new List<string> { "j", "k", "l", "p", "q", "r" };
var updatedList = new List<string> { "m", "n", "o", "p", "q", "r" };
CancellationTokenSource cts = new();
CancellationToken cancellationToken = cts.Token;
cts.Cancel();
//Assert
Assert.Throws<OperationCanceledException>(() =>
{
//Act
var actualResult = Delta<string>.CalculateDelta(updatedList, originalList,
StringComparer.InvariantCultureIgnoreCase, cancellationToken);
});
}
[Test]
public void UpdateDbSetAsync_TokenCancelled_ThrowsException()
{
//Arrange
var originalList = new List<string> { "j", "k", "l", "p", "q", "r" };
var updatedList = new List<string> { "m", "n", "o", "p", "q", "r" };
CancellationTokenSource cts = new();
CancellationToken cancellationToken = cts.Token;
var delta = Delta<string>.CalculateDelta(updatedList, originalList,
StringComparer.InvariantCultureIgnoreCase, cancellationToken);
cts.Cancel();
var mockDBSet = GetQueryableMockDbSet(originalList);
//Assert
Assert.ThrowsAsync<OperationCanceledException>(async () =>
{
//Act
await delta.UpdateDbSetAsync(mockDBSet, cancellationToken);
});
}
[Test]
public async Task UpdateDbSetAsync_UpdateCompletes_UpdatedDBSetContainsExpectedValues()
{
//Arrange
var sourceList = new List<string> { "j", "k", "l", "p", "q", "r" };
var mockDbSet = GetQueryableMockDbSet(sourceList);
var originalList = new List<string>(sourceList);
var updatedList = new List<string> { "m", "n", "o", "p", "q", "r" };
CancellationTokenSource cts = new();
CancellationToken cancellationToken = cts.Token;
var delta = Delta<string>.CalculateDelta(updatedList, originalList,
StringComparer.InvariantCultureIgnoreCase, cancellationToken);
//Act
await delta.UpdateDbSetAsync(mockDbSet, cancellationToken);
//Assert
Assert.That(mockDbSet.Count(), Is.EqualTo(6) );
foreach (var entry in mockDbSet)
Assert.That(updatedList.Contains(entry), Is.True);
}
}