Files
2026-03-11 11:18:25 -05:00

129 lines
5.0 KiB
C#

using System;
using System.Reflection;
using System.Linq;
using System.Collections.Generic;
using Xunit;
using Landmark.OLA.Tests.TestData;
using Landmark.OLA.Models.Loan;
using Landmark.OLA.Models;
namespace Landmark.OLA.Tests
{
public class ModelValidatorTest
{
[Theory]
[MemberData(nameof(TestIndividuals.GetValidTestIndividuals), MemberType = typeof(TestIndividuals))]
[MemberData(nameof(TestAddresses.GetValidTestAddresses), MemberType = typeof(TestAddresses))]
[MemberData(nameof(TestEmployers.GetValidTestEmployers), MemberType = typeof(TestEmployers))]
public void ExpectValidModelsTest(object testData)
{
ModelValidator.Validate(testData);
}
[Theory]
[MemberData(nameof(TestIndividuals.GetInvalidTestIndividuals), MemberType = typeof(TestIndividuals))]
[MemberData(nameof(TestAddresses.GetInvalidTestAddresses), MemberType = typeof(TestAddresses))]
[MemberData(nameof(TestEmployers.GetInvalidTestEmployers), MemberType = typeof(TestEmployers))]
public void ExpectInvalidModelsTest(object testData)
{
Assert.Throws<ArgumentException>(() => ModelValidator.Validate(testData));
}
[Fact]
public void VerifyDataAnnotations()
{
string nspace = "Landmark.OLA.Models";
//LoanApplication is in the namespace we want to look into
Assembly modelAssembly = typeof(LoanApplication).GetTypeInfo().Assembly;
var models = modelAssembly.GetTypes()
.Where(t => t.IsClass == true && string.Equals(t.Namespace, nspace, StringComparison.Ordinal))
.ToArray();
var missingValidation = new List<string>();
foreach(var model in models)
{
var fields = model.GetProperties()
.Where(x => !x.PropertyType.Namespace.StartsWith("Landmark")
&& x.PropertyType != typeof(bool)
&& x.PropertyType != typeof(Guid)
&& x.PropertyType != typeof(Enum));
foreach (var field in fields)
{
var hasSizeValidation = false;
var fieldType = field.PropertyType;
if (fieldType.IsGenericType)
{
if (fieldType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
fieldType = Nullable.GetUnderlyingType(fieldType);
}
else
{
fieldType = fieldType.GetGenericArguments()[0];
}
}
if (fieldType.BaseType == typeof(Enum)
|| fieldType == typeof(bool)
|| fieldType == typeof(Guid)
|| fieldType == typeof(DateTime)
|| fieldType.IsClass)
{
//enum, bool, guid are restricted to specific sizes or values
//DateTime seems safe?
//Landmark classes will already have their validation checked
hasSizeValidation = true;
}
if(field.SetMethod?.IsPrivate ?? false)
{
//If inbound data ins't accepted we won't require validation
hasSizeValidation = true;
}
if (!hasSizeValidation)
{
foreach (var attribute in field.GetCustomAttributes()
.Where(x => x.TypeId.ToString().StartsWith("System.ComponentModel.DataAnnotations")))
{
var sizeValidationAttributeTypes = new List<Type>
{
typeof(System.ComponentModel.DataAnnotations.MaxLengthAttribute),
typeof(System.ComponentModel.DataAnnotations.RangeAttribute),
typeof(System.ComponentModel.DataAnnotations.StringLengthAttribute),
};
if (sizeValidationAttributeTypes.Contains(attribute.GetType()))
{
hasSizeValidation = true;
}
}
}
if(!hasSizeValidation)
{
missingValidation.Add($"{model.Name} : {field.Name}");
}
}
}
Assert.Empty(missingValidation);
}
private T GetAttributeFrom<T>(object instance, string propertyName) where T : Attribute
{
var attrType = typeof(T);
var property = instance.GetType().GetProperty(propertyName);
return (T)property.GetCustomAttributes(attrType, false).First();
}
}
}