using AyCode.Core.Extensions;
using AyCode.Core.Interfaces;
using AyCode.Core.Serializers.Jsons;
using MessagePack;
using MongoDB.Bson.Serialization.Attributes;
using Newtonsoft.Json;
namespace AyCode.Core.Tests.TestModels;
#region Shared Enums
///
/// Common status enum for all test entities
///
public enum TestStatus
{
Pending = 0,
Active = 1,
Processing = 2,
Completed = 3,
Shipped = 4,
OnHold = 5
}
///
/// Priority levels for tasks and projects
///
public enum TestPriority
{
Low = 0,
Medium = 1,
High = 2,
Critical = 3
}
///
/// User roles for testing
///
public enum TestUserRole
{
User = 0,
Manager = 1,
Admin = 2
}
#endregion
#region Shared Reference Types (IId-based for $id/$ref testing)
///
/// Shared tag/label - used across multiple entities for cross-reference testing.
/// Implements IId<int> for semantic $id/$ref serialization.
///
public class SharedTag : IId
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string Color { get; set; } = "#000000";
public int Priority { get; set; }
public bool IsActive { get; set; } = true;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public string? Description { get; set; }
}
///
/// Shared category - for hierarchical cross-reference testing.
///
public class SharedCategory : IId
{
public int Id { get; set; }
public string Name { get; set; } = "";
public string? Description { get; set; }
public int SortOrder { get; set; }
public bool IsDefault { get; set; }
public int? ParentCategoryId { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; set; }
}
///
/// Shared user reference - appears in many places to test $ref deduplication.
///
public class SharedUser : IId
{
public int Id { get; set; }
public string Username { get; set; } = "";
public string Email { get; set; } = "";
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
public bool IsActive { get; set; } = true;
public TestUserRole Role { get; set; } = TestUserRole.User;
public DateTime? LastLoginAt { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public UserPreferences? Preferences { get; set; }
}
///
/// User preferences - non-IId nested object
///
public class UserPreferences
{
public string Theme { get; set; } = "light";
public string Language { get; set; } = "en-US";
public bool NotificationsEnabled { get; set; } = true;
public string? EmailDigestFrequency { get; set; }
}
#endregion
#region Non-IId Metadata (Newtonsoft numeric $id/$ref testing)
///
/// Non-IId metadata class - uses Newtonsoft PreserveReferencesHandling (numeric $id/$ref).
/// Does NOT implement IId, so uses standard Newtonsoft reference tracking.
///
public class MetadataInfo
{
public string Key { get; set; } = "";
public string Value { get; set; } = "";
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
///
/// Nested metadata for deep Newtonsoft reference testing
///
public MetadataInfo? ChildMetadata { get; set; }
}
#endregion
#region 5-Level Test Hierarchy (Order -> Item -> Pallet -> Measurement -> Point)
///
/// Level 1: Main order - root of the hierarchy
///
public class TestOrder : IId
{
public int Id { get; set; }
public string OrderNumber { get; set; } = "";
public TestStatus Status { get; set; } = TestStatus.Pending;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? PaidDateUtc { get; set; }
public decimal TotalAmount { get; set; }
// Level 2 collection
public List Items { get; set; } = [];
// Shared reference properties (for $id/$ref testing)
public SharedTag? PrimaryTag { get; set; }
public SharedTag? SecondaryTag { get; set; }
public SharedUser? Owner { get; set; }
public SharedCategory? Category { get; set; }
// Collection of shared references
public List Tags { get; set; } = [];
// Non-IId metadata (for Newtonsoft $ref testing)
public MetadataInfo? OrderMetadata { get; set; }
public MetadataInfo? AuditMetadata { get; set; }
public List MetadataList { get; set; } = [];
// NoMerge collection for testing replace behavior
[JsonNoMergeCollection]
public List NoMergeItems { get; set; } = [];
// Parent reference - ignored by all serializers to prevent circular references
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public object? Parent { get; set; }
}
///
/// Level 2: Order item with pallets
///
public class TestOrderItem : IId
{
public int Id { get; set; }
public string ProductName { get; set; } = "";
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public TestStatus Status { get; set; } = TestStatus.Pending;
// Level 3 collection
public List Pallets { get; set; } = [];
// Shared references
public SharedTag? Tag { get; set; }
public SharedUser? Assignee { get; set; }
public MetadataInfo? ItemMetadata { get; set; }
// Parent reference - ignored by all serializers to prevent circular references
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestOrder? ParentOrder { get; set; }
}
///
/// Level 3: Pallet containing measurements
///
public class TestPallet : IId
{
public int Id { get; set; }
public string PalletCode { get; set; } = "";
public int TrayCount { get; set; }
public TestStatus Status { get; set; } = TestStatus.Pending;
public double Weight { get; set; }
// Level 4 collection
public List Measurements { get; set; } = [];
// Shared references
public MetadataInfo? PalletMetadata { get; set; }
// Parent reference - ignored by all serializers to prevent circular references
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestOrderItem? ParentItem { get; set; }
}
///
/// Level 4: Measurement with multiple points
///
public class TestMeasurement : IId
{
public int Id { get; set; }
public string Name { get; set; } = "";
public double TotalWeight { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
// Level 5 collection
public List Points { get; set; } = [];
// Parent reference - ignored by all serializers to prevent circular references
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestPallet? ParentPallet { get; set; }
}
///
/// Level 5: Deepest level - measurement point
///
public class TestMeasurementPoint : IId
{
public int Id { get; set; }
public string Label { get; set; } = "";
public double Value { get; set; }
public DateTime MeasuredAt { get; set; } = DateTime.UtcNow;
// Parent reference - ignored by all serializers to prevent circular references
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestMeasurement? ParentMeasurement { get; set; }
}
#endregion
#region Guid-based IId types
///
/// Order with Guid Id - for testing Guid-based IId
///
public class TestGuidOrder : IId
{
public Guid Id { get; set; }
public string Code { get; set; } = "";
public List Items { get; set; } = [];
public int Count { get; set; }
}
///
/// Item with Guid Id
///
public class TestGuidItem : IId
{
public Guid Id { get; set; }
public string Name { get; set; } = "";
public int Qty { get; set; }
}
#endregion
#region Test-specific classes
///
/// Simulates NopCommerce GenericAttribute - stores key-value pairs where DateTime values
/// are stored as strings in the database.
///
public class TestGenericAttribute
{
public int Id { get; set; }
public string Key { get; set; } = "";
public string Value { get; set; } = "";
}
///
/// DTO with GenericAttributes collection - simulates OrderDto with string-stored DateTime values.
/// This reproduces the production bug where Binary serialization was thought to corrupt DateTime strings.
///
public class TestDtoWithGenericAttributes : IId
{
public int Id { get; set; }
public string Name { get; set; } = "";
public List GenericAttributes { get; set; } = [];
}
///
/// Order with nullable collections for null vs empty testing
///
public class TestOrderWithNullableCollections
{
public int Id { get; set; }
public string OrderNumber { get; set; } = "";
public List? Items { get; set; }
public List? Tags { get; set; }
}
///
/// Class with all primitive types for WASM/serialization testing
///
public class PrimitiveTestClass
{
public int IntValue { get; set; }
public long LongValue { get; set; }
public double DoubleValue { get; set; }
public decimal DecimalValue { get; set; }
public float FloatValue { get; set; }
public bool BoolValue { get; set; }
public string StringValue { get; set; } = "";
public Guid GuidValue { get; set; }
public DateTime DateTimeValue { get; set; }
public TestStatus EnumValue { get; set; }
public byte ByteValue { get; set; }
public short ShortValue { get; set; }
public int? NullableInt { get; set; }
public int? NullableIntNull { get; set; }
}
///
/// Class with extended primitive types for full serializer coverage.
/// Includes DateTimeOffset, TimeSpan, Dictionary, null properties.
///
public class ExtendedPrimitiveTestClass
{
public int Id { get; set; }
public string Name { get; set; } = "";
// Extended primitive types not covered in PrimitiveTestClass
public DateTimeOffset DateTimeOffsetValue { get; set; }
public TimeSpan TimeSpanValue { get; set; }
public uint UIntValue { get; set; }
public ulong ULongValue { get; set; }
public ushort UShortValue { get; set; }
public sbyte SByteValue { get; set; }
public char CharValue { get; set; }
// Dictionary property for WriteDictionary coverage in object context
public Dictionary? Counts { get; set; }
public Dictionary? Labels { get; set; }
// Nullable properties that will be null
public string? NullString { get; set; }
public TestOrderItem? NullObject { get; set; }
// Nested object for complex serialization
public SharedTag? Tag { get; set; }
}
///
/// Class with array of objects containing null items for WriteNull coverage
///
public class ObjectWithNullItems
{
public int Id { get; set; }
public List