160 lines
5.6 KiB
C#
Executable File
160 lines
5.6 KiB
C#
Executable File
using System.ComponentModel.DataAnnotations;
|
|
using ZB.MOM.WW.CBDD.Bson;
|
|
using ZB.MOM.WW.CBDD.Shared;
|
|
using ZB.MOM.WW.CBDD.Shared.TestDbContext_TestDbContext_Mappers;
|
|
|
|
namespace ZB.MOM.WW.CBDD.Tests
|
|
{
|
|
public class AttributeTests
|
|
{
|
|
// Use full path for mapper until we are sure of the namespace
|
|
private ZB_MOM_WW_CBDD_Shared_AnnotatedUserMapper CreateMapper() => new();
|
|
|
|
private readonly System.Collections.Concurrent.ConcurrentDictionary<string, ushort> _keyMap = new(StringComparer.OrdinalIgnoreCase);
|
|
private readonly System.Collections.Concurrent.ConcurrentDictionary<ushort, string> _keys = new();
|
|
|
|
/// <summary>
|
|
/// Initializes lookup maps used by attribute mapper tests.
|
|
/// </summary>
|
|
public AttributeTests()
|
|
{
|
|
ushort id = 1;
|
|
string[] keys = ["_id", "display_name", "age", "location", "0", "1"];
|
|
foreach (var key in keys)
|
|
{
|
|
_keyMap[key] = id;
|
|
_keys[id] = key;
|
|
id++;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies table attribute mapping resolves the expected collection name.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Test_Table_Attribute_Mapping()
|
|
{
|
|
// Verify that the generated mapper has the correct collection name
|
|
var mapper = CreateMapper();
|
|
mapper.CollectionName.ShouldBe("test.custom_users");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies required attribute validation is enforced.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Test_Required_Validation()
|
|
{
|
|
var mapper = CreateMapper();
|
|
var user = new AnnotatedUser { Name = "" }; // Required name is empty
|
|
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
|
|
|
bool thrown = false;
|
|
try
|
|
{
|
|
mapper.Serialize(user, writer);
|
|
}
|
|
catch (ValidationException)
|
|
{
|
|
thrown = true;
|
|
}
|
|
thrown.ShouldBeTrue("Should throw ValidationException for empty Name.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies string length attribute validation is enforced.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Test_StringLength_Validation()
|
|
{
|
|
var mapper = CreateMapper();
|
|
var user = new AnnotatedUser { Name = "Jo" }; // Too short
|
|
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
|
|
|
bool thrown = false;
|
|
try { mapper.Serialize(user, writer); } catch (ValidationException) { thrown = true; }
|
|
thrown.ShouldBeTrue("Should throw ValidationException for Name too short.");
|
|
|
|
user.Name = new string('A', 51); // Too long
|
|
thrown = false;
|
|
try { mapper.Serialize(user, writer); } catch (ValidationException) { thrown = true; }
|
|
thrown.ShouldBeTrue("Should throw ValidationException for Name too long.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies range attribute validation is enforced.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Test_Range_Validation()
|
|
{
|
|
var mapper = CreateMapper();
|
|
var user = new AnnotatedUser { Name = "John", Age = 200 }; // Out of range
|
|
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
|
|
|
bool thrown = false;
|
|
try { mapper.Serialize(user, writer); } catch (ValidationException) { thrown = true; }
|
|
thrown.ShouldBeTrue("Should throw ValidationException for Age out of range.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies column attribute maps to the expected BSON field name.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Test_Column_Name_Mapping()
|
|
{
|
|
var mapper = CreateMapper();
|
|
var user = new AnnotatedUser { Name = "John", Age = 30 };
|
|
var buffer = new byte[1024];
|
|
var writer = new BsonSpanWriter(buffer, _keyMap);
|
|
|
|
mapper.Serialize(user, writer);
|
|
|
|
var reader = new BsonSpanReader(buffer, _keys);
|
|
reader.ReadDocumentSize();
|
|
|
|
bool foundDisplayName = false;
|
|
while (reader.Remaining > 0)
|
|
{
|
|
var type = reader.ReadBsonType();
|
|
if (type == BsonType.EndOfDocument) break;
|
|
|
|
var name = reader.ReadElementHeader();
|
|
if (name == "display_name") foundDisplayName = true;
|
|
reader.SkipValue(type);
|
|
}
|
|
|
|
foundDisplayName.ShouldBeTrue("BSON field name should be 'display_name' from [Column] attribute.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies not-mapped attribute excludes properties from BSON serialization.
|
|
/// </summary>
|
|
[Fact]
|
|
public void Test_NotMapped_Attribute()
|
|
{
|
|
var mapper = CreateMapper();
|
|
var user = new AnnotatedUser { Name = "John", Age = 30 };
|
|
var buffer = new byte[1024];
|
|
var writer = new BsonSpanWriter(buffer, _keyMap);
|
|
|
|
mapper.Serialize(user, writer);
|
|
|
|
var reader = new BsonSpanReader(buffer, _keys);
|
|
reader.ReadDocumentSize();
|
|
|
|
bool foundComputed = false;
|
|
while (reader.Remaining > 0)
|
|
{
|
|
var type = reader.ReadBsonType();
|
|
if (type == BsonType.EndOfDocument) break;
|
|
|
|
var name = reader.ReadElementHeader();
|
|
if (name == "ComputedInfo") foundComputed = true;
|
|
reader.SkipValue(type);
|
|
}
|
|
|
|
foundComputed.ShouldBeFalse("ComputedInfo should not be mapped to BSON.");
|
|
}
|
|
}
|
|
}
|