|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Mvc.DataAnnotations;
namespace Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
public class ValidatorCacheTest
{
[Fact]
public void GetValidators_CachesAllValidators()
{
// Arrange
var cache = new ValidatorCache();
var metadata = new TestModelMetadataProvider().GetMetadataForProperty(typeof(TypeWithProperty), "Property1");
var validatorProvider = TestModelValidatorProvider.CreateDefaultProvider();
// Act - 1
var validators1 = cache.GetValidators(metadata, validatorProvider);
// Assert - 1
var attribute1 = Assert.IsType<DataAnnotationsModelValidator>(validators1[0]).Attribute;
var attribute2 = Assert.IsType<DataAnnotationsModelValidator>(validators1[1]).Attribute;
Assert.Contains(attribute1, metadata.ValidatorMetadata); // Copied by provider
Assert.Contains(attribute2, metadata.ValidatorMetadata); // Copied by provider
// Act - 2
var validators2 = cache.GetValidators(metadata, validatorProvider);
// Assert - 2
Assert.Same(validators1, validators2);
Assert.Contains(validators1[0], validators2); // Cached
Assert.Contains(validators1[1], validators2); // Cached
}
[Fact]
public void GetValidators_DoesNotCacheValidatorsWithIsReusableFalse()
{
// Arrange
var cache = new ValidatorCache();
var metadata = new TestModelMetadataProvider().GetMetadataForProperty(typeof(TypeWithProperty), "Property1");
var validatorProvider = new ProviderWithNonReusableValidators();
// Act - 1
var validators1 = cache.GetValidators(metadata, validatorProvider);
// Assert - 1
var validator1 = Assert.IsType<DataAnnotationsModelValidator>(validators1[0]);
var validator2 = Assert.IsType<DataAnnotationsModelValidator>(validators1[1]);
Assert.Contains(validator1.Attribute, metadata.ValidatorMetadata); // Copied by provider
Assert.Contains(validator2.Attribute, metadata.ValidatorMetadata); // Copied by provider
// Act - 2
var validators2 = cache.GetValidators(metadata, validatorProvider);
// Assert - 2
Assert.NotSame(validators1, validators2);
var requiredValidator = Assert.Single(validators2.Where(v => (v as DataAnnotationsModelValidator).Attribute is RequiredAttribute));
Assert.Contains(requiredValidator, validators1); // cached
var stringLengthValidator = Assert.Single(validators2.Where(v => (v as DataAnnotationsModelValidator).Attribute is StringLengthAttribute));
Assert.DoesNotContain(stringLengthValidator, validators1); // not cached
}
private class TypeWithProperty
{
[Required]
[StringLength(10)]
public string Property1 { get; set; }
}
private class ProviderWithNonReusableValidators : IModelValidatorProvider
{
public void CreateValidators(ModelValidatorProviderContext context)
{
for (var i = 0; i < context.Results.Count; i++)
{
var validatorItem = context.Results[i];
if (validatorItem.Validator != null)
{
continue;
}
var attribute = validatorItem.ValidatorMetadata as ValidationAttribute;
if (attribute == null)
{
continue;
}
var validator = new DataAnnotationsModelValidator(
new ValidationAttributeAdapterProvider(),
attribute,
stringLocalizer: null);
validatorItem.Validator = validator;
if (attribute is RequiredAttribute)
{
validatorItem.IsReusable = true;
}
}
}
}
}
|