namespace AyCode.Core.Tests.Serialization; /// /// Test models for binary serializer tests. /// public static class AcSerializerModels { public class TestSimpleClass { public int Id { get; set; } public string Name { get; set; } = ""; public double Value { get; set; } public bool IsActive { get; set; } } public class TestNestedClass { public int Id { get; set; } public string Name { get; set; } = ""; public TestSimpleClass? Child { get; set; } } public class TestClassWithList { public int Id { get; set; } public List Items { get; set; } = new(); } public class TestClassWithRepeatedStrings { public string Field1 { get; set; } = ""; public string Field2 { get; set; } = ""; public string Field3 { get; set; } = ""; public string Field4 { get; set; } = ""; } public class TestClassWithLongPropertyNames { public string FirstProperty { get; set; } = ""; public string SecondProperty { get; set; } = ""; public string ThirdProperty { get; set; } = ""; public string FourthProperty { get; set; } = ""; } public class TestClassWithMixedStrings { public int Id { get; set; } public string ShortName { get; set; } = ""; public string LongName { get; set; } = ""; public string Description { get; set; } = ""; public string Tag { get; set; } = ""; } public class TestNestedStructure { public string RootName { get; set; } = ""; public List Level1Items { get; set; } = new(); } public class TestLevel1 { public string Level1Name { get; set; } = ""; public List Level2Items { get; set; } = new(); } public class TestLevel2 { public string Level2Name { get; set; } = ""; public string Value { get; set; } = ""; } public class TestClassWithRepeatedValues { public int Id { get; set; } public string Status { get; set; } = ""; public string Category { get; set; } = ""; public string Priority { get; set; } = ""; } public class TestClassWithNameValue { public string Name { get; set; } = ""; public string Value { get; set; } = ""; } public class TestClassWithNullableStrings { public int Id { get; set; } public string RequiredName { get; set; } = ""; public string? OptionalName { get; set; } public string? Description { get; set; } } public class TestCustomerLikeDto { public int Id { get; set; } public string FirstName { get; set; } = ""; public string LastName { get; set; } = ""; public string Email { get; set; } = ""; public string Company { get; set; } = ""; public string Department { get; set; } = ""; public string Role { get; set; } = ""; public string Status { get; set; } = ""; public List Attributes { get; set; } = new(); } public class TestAttribute { public string Key { get; set; } = ""; public string Value { get; set; } = ""; } public class TestHighReuseDto { public int Id { get; set; } public string CategoryCode { get; set; } = ""; public string StatusCode { get; set; } = ""; public string TypeCode { get; set; } = ""; public string PriorityCode { get; set; } = ""; public string UniqueField { get; set; } = ""; } public class TestClassWithNullableProperties { public int Id { get; set; } public int? NullableInt { get; set; } public int? NullableIntNull { get; set; } public long? NullableLong { get; set; } public long? NullableLongNull { get; set; } public double? NullableDouble { get; set; } public double? NullableDoubleNull { get; set; } public decimal? NullableDecimal { get; set; } public decimal? NullableDecimalNull { get; set; } public DateTime? NullableDateTime { get; set; } public DateTime? NullableDateTimeNull { get; set; } public Guid? NullableGuid { get; set; } public Guid? NullableGuidNull { get; set; } public bool? NullableBool { get; set; } public bool? NullableBoolNull { get; set; } } public class TestParentWithNullableChild { public int Id { get; set; } public string Name { get; set; } = ""; public TestClassWithNullableProperties? Child { get; set; } } /// /// Test model mimicking StockTaking entity structure. /// /// public class TestStockTaking { public int Id { get; set; } public DateTime StartDateTime { get; set; } public bool IsClosed { get; set; } public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? StockTakingItems { get; set; } } /// /// Test model mimicking StockTakingItem entity structure. /// /// public class TestStockTakingItem { public int Id { get; set; } public int StockTakingId { get; set; } public int ProductId { get; set; } public bool IsMeasured { get; set; } public int OriginalStockQuantity { get; set; } public int MeasuredStockQuantity { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? StockTakingItemPallets { get; set; } } /// /// Test model mimicking StockTakingItemPallet/MeasuringItemPalletBase entity structure. /// Contains nullable int properties (CreatorId, ModifierId) that caused the production bug. /// public class TestStockTakingItemPallet { public int Id { get; set; } public int StockTakingItemId { get; set; } public int TrayQuantity { get; set; } public double TareWeight { get; set; } public double PalletWeight { get; set; } public double GrossWeight { get; set; } public bool IsMeasured { get; set; } public int? CreatorId { get; set; } public int? ModifierId { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } public class TestEntityWithDateTimeAndInt { public int Id { get; set; } public int IntValue { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public int StatusCode { get; set; } public string Name { get; set; } = ""; } public class TestEntityWithManyIntsBeforeDateTime { public int Id { get; set; } public int Value1 { get; set; } public int Value2 { get; set; } public int Value3 { get; set; } public int Value4 { get; set; } public int Value5 { get; set; } public DateTime FirstDateTime { get; set; } public DateTime SecondDateTime { get; set; } public int FinalValue { get; set; } } public class TestParentEntityWithDateTimeChild { public int ParentId { get; set; } public string ParentName { get; set; } = ""; public TestEntityWithDateTimeAndInt? Child { get; set; } } public class TestParentWithDateTimeItemCollection { public int Id { get; set; } public string Name { get; set; } = ""; public DateTime Created { get; set; } public List? Items { get; set; } } /// /// Base class to simulate inheritance hierarchy like MgEntityBase. /// Id property is in base class, so reflection may return it last. /// public abstract class TestEntityBase { public int Id { get; set; } } /// /// Simulates MgStockTaking structure with inheritance. /// Properties are ordered: StartDateTime, IsClosed, StockTakingItems, Creator, Created, Modified /// Id comes from base class and may appear last in reflection. /// public class TestStockTakingWithInheritance : TestEntityBase { public DateTime StartDateTime { get; set; } public bool IsClosed { get; set; } public List? StockTakingItems { get; set; } public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } /// /// Simulates StockTakingItem with inheritance. /// public class TestStockTakingItemWithInheritance : TestEntityBase { public int StockTakingId { get; set; } public int ProductId { get; set; } public bool IsMeasured { get; set; } public int OriginalStockQuantity { get; set; } public int MeasuredStockQuantity { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? StockTakingItemPallets { get; set; } } /// /// Simulates MeasuringItemPalletBase with inheritance and ForeignKey pattern. /// public class TestStockTakingItemPalletWithInheritance : TestEntityBase { public int StockTakingItemId { get; set; } public int TrayQuantity { get; set; } public double TareWeight { get; set; } public double PalletWeight { get; set; } public double GrossWeight { get; set; } public bool IsMeasured { get; set; } public int? CreatorId { get; set; } public int? ModifierId { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } #region Schema Mismatch Tests /// /// Server-side model with extra properties that client doesn't know about. /// public class ServerStockTaking { public int Id { get; set; } public DateTime StartDateTime { get; set; } public bool IsClosed { get; set; } public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? StockTakingItems { get; set; } // Extra properties that client doesn't have public string? ExtraServerProperty1 { get; set; } public int ExtraServerProperty2 { get; set; } } /// /// Server-side item with Product navigation property. /// public class ServerStockTakingItem { public int Id { get; set; } public int StockTakingId { get; set; } public int ProductId { get; set; } public bool IsMeasured { get; set; } public int OriginalStockQuantity { get; set; } public int MeasuredStockQuantity { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } // Navigation property - this gets serialized on server! public ServerProductDto? Product { get; set; } public List? StockTakingItemPallets { get; set; } } /// /// Server-side product DTO. /// public class ServerProductDto { public int Id { get; set; } public string Name { get; set; } = ""; public string Description { get; set; } = ""; public double Price { get; set; } public int CategoryId { get; set; } } /// /// Server-side pallet with all properties. /// public class ServerStockTakingItemPallet { public int Id { get; set; } public int StockTakingItemId { get; set; } public int TrayQuantity { get; set; } public double TareWeight { get; set; } public double PalletWeight { get; set; } public double GrossWeight { get; set; } public bool IsMeasured { get; set; } public int? CreatorId { get; set; } public int? ModifierId { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } /// /// Client-side model - MISSING some properties that server sends. /// public class ClientStockTaking { public int Id { get; set; } public DateTime StartDateTime { get; set; } public bool IsClosed { get; set; } public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? StockTakingItems { get; set; } // Note: ExtraServerProperty1 and ExtraServerProperty2 are MISSING } /// /// Client-side item - MISSING Product navigation property. /// public class ClientStockTakingItem { public int Id { get; set; } public int StockTakingId { get; set; } public int ProductId { get; set; } public bool IsMeasured { get; set; } public int OriginalStockQuantity { get; set; } public int MeasuredStockQuantity { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } // Note: Product property is MISSING - server sends it, client skips it public List? StockTakingItemPallets { get; set; } } /// /// Client-side pallet. /// public class ClientStockTakingItemPallet { public int Id { get; set; } public int StockTakingItemId { get; set; } public int TrayQuantity { get; set; } public double TareWeight { get; set; } public double PalletWeight { get; set; } public double GrossWeight { get; set; } public bool IsMeasured { get; set; } public int? CreatorId { get; set; } public int? ModifierId { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } #endregion #region Circular Reference Test Models /// /// Parent entity with circular reference to child. /// public class CircularParent { public int Id { get; set; } public string Name { get; set; } = ""; public DateTime Created { get; set; } public DateTime Modified { get; set; } public int Creator { get; set; } public List? Children { get; set; } } /// /// Child entity with back-reference to parent (circular). /// public class CircularChild { public int Id { get; set; } public int ParentId { get; set; } public string Name { get; set; } = ""; public DateTime Created { get; set; } public DateTime Modified { get; set; } // Back-reference to parent - creates circular reference! public CircularParent? Parent { get; set; } public List? GrandChildren { get; set; } } /// /// Grandchild with back-reference. /// public class CircularGrandChild { public int Id { get; set; } public int ChildId { get; set; } public int? CreatorId { get; set; } public int? ModifierId { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } // Back-reference public CircularChild? Child { get; set; } } #endregion #region Generic Type Parameter Test Models /// /// Interface with fewer properties than implementation. /// public interface IGenericItem { int Id { get; set; } string Name { get; set; } } /// /// Implementation with MORE properties than interface. /// This is the exact pattern of StockTakingItem. /// public class GenericItemImpl : IGenericItem { public int Id { get; set; } public string Name { get; set; } = ""; // Extra properties NOT in interface public int ExtraInt { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public string Description { get; set; } = ""; } /// /// Parent class with generic type parameter for items. /// Similar to MgStockTaking<TStockTakingItem>. /// public class GenericParent where TItem : class, IGenericItem { public int Id { get; set; } public string Name { get; set; } = ""; public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? Items { get; set; } } /// /// Concrete implementation. /// Similar to StockTaking : MgStockTaking<StockTakingItem>. /// public class ConcreteParent : GenericParent { } #endregion #region Navigation Property Test Models /// /// Product entity that is NOT in the parent's generic type hierarchy. /// public class ProductEntity { public int Id { get; set; } public string Name { get; set; } = ""; public string Description { get; set; } = ""; public double Price { get; set; } public int CategoryId { get; set; } public DateTime Created { get; set; } } /// /// Item entity with navigation property to Product. /// This simulates StockTakingItem.Product. /// public class ItemWithNavigationProperty { public int Id { get; set; } public int ParentId { get; set; } public int ProductId { get; set; } public bool IsMeasured { get; set; } public int Quantity { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } // Navigation property - NOT in parent's generic type! // When populated, its properties need to be in metadata table too! public ProductEntity? Product { get; set; } } /// /// Parent entity with items that have navigation properties. /// This simulates StockTaking with StockTakingItems that have Product. /// public class ParentWithNavigatingItems { public int Id { get; set; } public string Name { get; set; } = ""; public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } public List? Items { get; set; } } #endregion #region Property Order Test Models /// /// Simulates NopCommerce BaseEntity. /// public abstract class NopBaseEntity { public int Id { get; set; } } /// /// Simulates MgEntityBase : BaseEntity. /// public abstract class SimMgEntityBase : NopBaseEntity { public override string ToString() => $"{GetType().Name}; Id: {Id}"; } /// /// Simulates MgStockTaking with exact property order from production. /// CRITICAL: Property order in code may differ from reflection order! /// public abstract class SimMgStockTaking : SimMgEntityBase where TStockTakingItem : class { public DateTime StartDateTime { get; set; } public bool IsClosed { get; set; } public List? StockTakingItems { get; set; } public int Creator { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } /// /// Simulates the concrete StockTaking class. /// public class SimStockTaking : SimMgStockTaking { } /// /// Simulates StockTakingItem with navigation properties. /// public class SimStockTakingItem : SimMgEntityBase { public int StockTakingId { get; set; } public int ProductId { get; set; } public bool IsMeasured { get; set; } public int OriginalStockQuantity { get; set; } public int MeasuredStockQuantity { get; set; } // Navigation property back to parent (circular!) public SimStockTaking? StockTaking { get; set; } public DateTime Created { get; set; } public DateTime Modified { get; set; } } #endregion }