AyCode.Core/AyCode.Core.Tests/Serialization/AcBinarySerializerCircularR...

161 lines
5.7 KiB
C#

using AyCode.Core.Extensions;
using static AyCode.Core.Tests.Serialization.AcSerializerModels;
namespace AyCode.Core.Tests.Serialization;
/// <summary>
/// Tests for circular reference handling with back-navigation properties.
/// </summary>
[TestClass]
public class AcBinarySerializerCircularReferenceTests
{
/// <summary>
/// CRITICAL TEST: Circular references with back-navigation properties.
/// This simulates the exact production scenario where:
/// - StockTaking has StockTakingItems collection
/// - StockTakingItem has StockTaking back-reference (circular!)
/// - StockTakingItem has Product navigation property
/// </summary>
[TestMethod]
public void Deserialize_CircularReference_ParentChildBackReference()
{
var parent = new CircularParent
{
Id = 1,
Name = "Parent",
Created = new DateTime(2025, 1, 24, 15, 25, 0, DateTimeKind.Utc),
Modified = DateTime.UtcNow,
Creator = 6,
Children = new List<CircularChild>()
};
var child = new CircularChild
{
Id = 10,
ParentId = 1,
Name = "Child",
Created = DateTime.UtcNow.AddHours(-1),
Modified = DateTime.UtcNow,
Parent = parent,
GrandChildren = new List<CircularGrandChild>()
};
var grandChild = new CircularGrandChild
{
Id = 100,
ChildId = 10,
CreatorId = 6,
ModifierId = null,
Created = DateTime.UtcNow,
Modified = DateTime.UtcNow,
Child = child
};
child.GrandChildren.Add(grandChild);
parent.Children.Add(child);
var binary = parent.ToBinary();
var result = binary.BinaryTo<CircularParent>();
Assert.IsNotNull(result);
Assert.AreEqual(1, result.Id);
Assert.AreEqual(6, result.Creator, "Creator should be 6");
Assert.AreEqual(parent.Created.Ticks, result.Created.Ticks,
$"Created mismatch. Expected: {parent.Created}, Got: {result.Created}");
Assert.IsNotNull(result.Children);
Assert.AreEqual(1, result.Children.Count);
var resultChild = result.Children[0];
Assert.AreEqual(10, resultChild.Id);
Assert.AreEqual(resultChild.Created.Ticks, child.Created.Ticks, "Child.Created should match");
Assert.IsNotNull(resultChild.Parent, "Child.Parent back-reference should be resolved");
Assert.AreEqual(1, resultChild.Parent.Id, "Back-reference should point to same parent");
}
/// <summary>
/// Test list of parents with circular references.
/// </summary>
[TestMethod]
public void Deserialize_ListOfCircularReferences_AllItemsCorrect()
{
var parents = Enumerable.Range(1, 5).Select(p =>
{
var parent = new CircularParent
{
Id = p,
Name = $"Parent_{p}",
Created = DateTime.UtcNow.AddDays(-p),
Modified = DateTime.UtcNow,
Creator = p,
Children = new List<CircularChild>()
};
for (int c = 1; c <= 2; c++)
{
var child = new CircularChild
{
Id = p * 100 + c,
ParentId = p,
Name = $"Child_{p}_{c}",
Created = DateTime.UtcNow.AddHours(-c),
Modified = DateTime.UtcNow,
Parent = parent,
GrandChildren = new List<CircularGrandChild>()
};
for (int g = 1; g <= 2; g++)
{
child.GrandChildren.Add(new CircularGrandChild
{
Id = p * 1000 + c * 100 + g,
ChildId = child.Id,
CreatorId = g % 2 == 0 ? p : null,
ModifierId = g % 2 == 1 ? p * 2 : null,
Created = DateTime.UtcNow,
Modified = DateTime.UtcNow,
Child = child
});
}
parent.Children.Add(child);
}
return parent;
}).ToList();
var binary = parents.ToBinary();
var result = binary.BinaryTo<List<CircularParent>>();
Assert.IsNotNull(result);
Assert.AreEqual(5, result.Count);
for (int p = 0; p < 5; p++)
{
var original = parents[p];
var deserialized = result[p];
Assert.AreEqual(original.Id, deserialized.Id, $"Parent[{p}].Id mismatch");
Assert.AreEqual(original.Creator, deserialized.Creator, $"Parent[{p}].Creator mismatch");
Assert.AreEqual(original.Created.Ticks, deserialized.Created.Ticks,
$"Parent[{p}].Created mismatch. Expected: {original.Created}, Got: {deserialized.Created}");
Assert.IsNotNull(deserialized.Children, $"Parent[{p}].Children is null");
Assert.AreEqual(2, deserialized.Children.Count, $"Parent[{p}].Children.Count mismatch");
for (int c = 0; c < 2; c++)
{
var origChild = original.Children![c];
var deserChild = deserialized.Children[c];
Assert.AreEqual(origChild.Id, deserChild.Id, $"Parent[{p}].Children[{c}].Id mismatch");
Assert.AreEqual(origChild.Created.Ticks, deserChild.Created.Ticks,
$"Parent[{p}].Children[{c}].Created mismatch");
Assert.IsNotNull(deserChild.Parent, $"Parent[{p}].Children[{c}].Parent should not be null");
}
}
}
}