aspnetcore/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/Metadata/ModelAttributesTest.cs

270 lines
9.7 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class ModelAttributesTest
{
[Fact]
public void GetAttributesForBaseProperty_IncludesMetadataAttributes()
{
// Arrange
var modelType = typeof(BaseViewModel);
var property = modelType.GetRuntimeProperties().FirstOrDefault(p => p.Name == nameof(BaseModel.BaseProperty));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(modelType, property);
// Assert
Assert.Single(attributes.Attributes.OfType<RequiredAttribute>());
Assert.Single(attributes.Attributes.OfType<StringLengthAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<RequiredAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<StringLengthAttribute>());
}
[Fact]
public void GetAttributesForTestProperty_ModelOverridesMetadataAttributes()
{
// Arrange
var modelType = typeof(BaseViewModel);
var property = modelType.GetRuntimeProperties().FirstOrDefault(p => p.Name == nameof(BaseModel.TestProperty));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(modelType, property);
// Assert
var rangeAttributes = attributes.Attributes.OfType<RangeAttribute>().ToArray();
Assert.NotNull(rangeAttributes[0]);
Assert.Equal(0, (int)rangeAttributes[0].Minimum);
Assert.Equal(10, (int)rangeAttributes[0].Maximum);
Assert.NotNull(rangeAttributes[1]);
Assert.Equal(10, (int)rangeAttributes[1].Minimum);
Assert.Equal(100, (int)rangeAttributes[1].Maximum);
Assert.Single(attributes.Attributes.OfType<FromHeaderAttribute>());
rangeAttributes = attributes.PropertyAttributes.OfType<RangeAttribute>().ToArray();
Assert.NotNull(rangeAttributes[0]);
Assert.Equal(0, (int)rangeAttributes[0].Minimum);
Assert.Equal(10, (int)rangeAttributes[0].Maximum);
Assert.NotNull(rangeAttributes[1]);
Assert.Equal(10, (int)rangeAttributes[1].Minimum);
Assert.Equal(100, (int)rangeAttributes[1].Maximum);
Assert.Single(attributes.PropertyAttributes.OfType<FromHeaderAttribute>());
}
[Fact]
public void GetAttributesForBasePropertyFromDerivedModel_IncludesMetadataAttributes()
{
// Arrange
var modelType = typeof(DerivedViewModel);
var property = modelType.GetRuntimeProperties().FirstOrDefault(p => p.Name == nameof(BaseModel.BaseProperty));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(modelType, property);
// Assert
Assert.Single(attributes.Attributes.OfType<RequiredAttribute>());
Assert.Single(attributes.Attributes.OfType<StringLengthAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<RequiredAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<StringLengthAttribute>());
}
[Fact]
public void GetAttributesForTestPropertyFromDerived_IncludesMetadataAttributes()
{
// Arrange
var modelType = typeof(DerivedViewModel);
var property = modelType.GetRuntimeProperties().FirstOrDefault(p => p.Name == nameof(BaseModel.TestProperty));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(modelType, property);
// Assert
Assert.Single(attributes.Attributes.OfType<RequiredAttribute>());
Assert.Single(attributes.Attributes.OfType<StringLengthAttribute>());
Assert.DoesNotContain(typeof(RangeAttribute), attributes.Attributes);
Assert.Single(attributes.PropertyAttributes.OfType<RequiredAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<StringLengthAttribute>());
Assert.DoesNotContain(typeof(RangeAttribute), attributes.PropertyAttributes);
}
[Fact]
public void GetAttributesForVirtualPropertyFromDerived_IncludesMetadataAttributes()
{
// Arrange
var modelType = typeof(DerivedViewModel);
var property = modelType.GetRuntimeProperties().FirstOrDefault(p => p.Name == nameof(BaseModel.VirtualProperty));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(modelType, property);
// Assert
Assert.Single(attributes.Attributes.OfType<RequiredAttribute>());
Assert.Single(attributes.Attributes.OfType<RangeAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<RequiredAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<RangeAttribute>());
}
[Fact]
public void GetFromServiceAttributeFromBase_IncludesMetadataAttributes()
{
// Arrange
var modelType = typeof(DerivedViewModel);
var property = modelType.GetRuntimeProperties().FirstOrDefault(p => p.Name == nameof(BaseModel.RouteValue));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(modelType, property);
// Assert
Assert.Single(attributes.Attributes.OfType<RequiredAttribute>());
Assert.Single(attributes.Attributes.OfType<FromRouteAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<RequiredAttribute>());
Assert.Single(attributes.PropertyAttributes.OfType<FromRouteAttribute>());
}
[Fact]
public void GetAttributesForType_IncludesMetadataAttributes()
{
// Arrange & Act
var attributes = ModelAttributes.GetAttributesForType(typeof(BaseViewModel));
// Assert
Assert.Single(attributes.Attributes.OfType<ClassValidator>());
Assert.Single(attributes.TypeAttributes.OfType<ClassValidator>());
}
[Fact]
public void GetAttributesForType_PropertyAttributes_IsNull()
{
// Arrange & Act
var attributes = ModelAttributes.GetAttributesForType(typeof(BaseViewModel));
// Assert
Assert.Null(attributes.PropertyAttributes);
}
[Fact]
public void GetAttributesForProperty_MergedAttributes()
{
// Arrange
var property = typeof(MergedAttributes).GetRuntimeProperty(nameof(MergedAttributes.Property));
// Act
var attributes = ModelAttributes.GetAttributesForProperty(typeof(MergedAttributes), property);
// Assert
Assert.Equal(3, attributes.Attributes.Count);
Assert.IsType<RequiredAttribute>(attributes.Attributes[0]);
Assert.IsType<RangeAttribute>(attributes.Attributes[1]);
Assert.IsType<ClassValidator>(attributes.Attributes[2]);
Assert.Equal(2, attributes.PropertyAttributes.Count);
Assert.IsType<RequiredAttribute>(attributes.PropertyAttributes[0]);
Assert.IsType<RangeAttribute>(attributes.PropertyAttributes[1]);
var attribute = Assert.Single(attributes.TypeAttributes);
Assert.IsType<ClassValidator>(attribute);
}
[ClassValidator]
private class BaseModel
{
[StringLength(10)]
public string BaseProperty { get; set; }
[Range(10,100)]
[FromHeader]
public string TestProperty { get; set; }
[Required]
public virtual int VirtualProperty { get; set; }
[FromRoute]
public string RouteValue { get; set; }
}
private class DerivedModel : BaseModel
{
[Required]
public string DerivedProperty { get; set; }
[Required]
public new string TestProperty { get; set; }
[Range(10,100)]
public override int VirtualProperty { get; set; }
}
[ModelMetadataType(typeof(BaseModel))]
private class BaseViewModel
{
[Range(0,10)]
public string TestProperty { get; set; }
[Required]
public string BaseProperty { get; set; }
[Required]
public string RouteValue { get; set; }
}
[ModelMetadataType(typeof(DerivedModel))]
private class DerivedViewModel : BaseViewModel
{
[StringLength(2)]
public new string TestProperty { get; set; }
public int VirtualProperty { get; set; }
}
public interface ICalculator
{
int Operation(char @operator, int left, int right);
}
private class ClassValidator : ValidationAttribute
{
public override Boolean IsValid(Object value)
{
return true;
}
}
[ModelMetadataType(typeof(MergedAttributesMetadata))]
private class MergedAttributes
{
[Required]
public PropertyType Property { get; set; }
}
private class MergedAttributesMetadata
{
[Range(0, 10)]
public MetadataPropertyType Property { get; set; }
}
[ClassValidator]
private class PropertyType
{
}
[Bind]
private class MetadataPropertyType
{
}
}
}