using System.ComponentModel.DataAnnotations; using System.Linq; using Shouldly; using Xunit; namespace Volo.Abp.ObjectExtending { public class ObjectExtensionManager_Tests { private readonly ObjectExtensionManager _objectExtensionManager; public ObjectExtensionManager_Tests() { _objectExtensionManager = new ObjectExtensionManager(); } [Fact] public void Should_Not_Add_Same_Property_Multiple_Times() { _objectExtensionManager .AddOrUpdateProperty("TestProp") .AddOrUpdateProperty("TestProp"); var objectExtension = _objectExtensionManager.GetOrNull(); objectExtension.ShouldNotBeNull(); var properties = objectExtension.GetProperties(); properties.Count.ShouldBe(1); properties.FirstOrDefault(p => p.Name == "TestProp").ShouldNotBeNull(); } [Fact] public void Should_Update_Property_Configuration() { _objectExtensionManager .AddOrUpdateProperty( "TestProp", options => { options.Configuration["TestConfig1"] = "TestConfig1-Value"; } ).AddOrUpdateProperty( "TestProp", options => { options.Configuration["TestConfig2"] = "TestConfig2-Value"; } ); var objectExtension = _objectExtensionManager.GetOrNull(); objectExtension.ShouldNotBeNull(); var property = objectExtension.GetPropertyOrNull("TestProp"); property.ShouldNotBeNull(); property.Configuration["TestConfig1"].ShouldBe("TestConfig1-Value"); property.Configuration["TestConfig2"].ShouldBe("TestConfig2-Value"); } [Fact] public void Should_Automatically_Add_RequiredAttribute_To_Non_Nullable_Types_And_Enums() { _objectExtensionManager .AddOrUpdateProperty("IntProp") .AddOrUpdateProperty("BoolProp") .AddOrUpdateProperty("NullableIntProp") .AddOrUpdateProperty("StringProp") .AddOrUpdateProperty("EnumProp"); _objectExtensionManager .GetPropertyOrNull("IntProp") .Attributes .ShouldContain(x => x is RequiredAttribute); _objectExtensionManager .GetPropertyOrNull("BoolProp") .Attributes .ShouldContain(x => x is RequiredAttribute); _objectExtensionManager .GetPropertyOrNull("EnumProp") .Attributes .ShouldContain(x => x is RequiredAttribute); _objectExtensionManager .GetPropertyOrNull("NullableIntProp") .Attributes .ShouldNotContain(x => x is RequiredAttribute); _objectExtensionManager .GetPropertyOrNull("StringProp") .Attributes .ShouldNotContain(x => x is RequiredAttribute); } [Fact] public void Should_Automatically_Add_EnumDataTypeAttribute_For_Enums() { _objectExtensionManager .AddOrUpdateProperty("EnumProp"); _objectExtensionManager .GetPropertyOrNull("EnumProp") .Attributes .ShouldContain(x => x is EnumDataTypeAttribute); } [Fact] public void Should_Be_Able_To_Clear_Auto_Added_Attributes() { _objectExtensionManager .AddOrUpdateProperty("IntProp", property => { property.Attributes.Clear(); }); _objectExtensionManager .GetPropertyOrNull("IntProp") .Attributes .ShouldNotContain(x => x is RequiredAttribute); } [Fact] public void Should_Set_DefaultValues() { _objectExtensionManager .AddOrUpdateProperty("IntProp") .AddOrUpdateProperty("IntPropWithCustomDefaultValue", property => { property.DefaultValue = 42; }) .AddOrUpdateProperty("BoolProp") .AddOrUpdateProperty("NullableIntProp") .AddOrUpdateProperty("NullableIntPropWithCustomDefaultValueFactory", property => { property.DefaultValueFactory = () => 2; }) .AddOrUpdateProperty("StringProp") .AddOrUpdateProperty("StringPropWithCustomDefaultValue", property => { property.DefaultValue = "custom-value"; }) .AddOrUpdateProperty("EnumProp", property => { property.DefaultValue = MyTestEnum.EnumValue2; }); _objectExtensionManager .GetPropertyOrNull("IntProp") .GetDefaultValue().ShouldBe(0); _objectExtensionManager .GetPropertyOrNull("IntPropWithCustomDefaultValue") .GetDefaultValue().ShouldBe(42); _objectExtensionManager .GetPropertyOrNull("BoolProp") .GetDefaultValue().ShouldBe(false); _objectExtensionManager .GetPropertyOrNull("NullableIntProp") .GetDefaultValue().ShouldBeNull(); var propWithDefaultValueFactory = _objectExtensionManager .GetPropertyOrNull("NullableIntPropWithCustomDefaultValueFactory"); propWithDefaultValueFactory.GetDefaultValue().ShouldBe(2); _objectExtensionManager .GetPropertyOrNull("StringProp") .GetDefaultValue().ShouldBeNull(); _objectExtensionManager .GetPropertyOrNull("StringPropWithCustomDefaultValue") .GetDefaultValue().ShouldBe("custom-value"); _objectExtensionManager .GetPropertyOrNull("EnumProp") .GetDefaultValue().ShouldBe(MyTestEnum.EnumValue2); } private class MyExtensibleObject : ExtensibleObject { } private enum MyTestEnum { EnumValue1, EnumValue2, } } }