129 lines
5.0 KiB
C#
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();
|
|
}
|
|
|
|
}
|
|
}
|