using System.ComponentModel.DataAnnotations; using System.Reflection; using Jiaowu.Api.Controllers; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; namespace Jiaowu.Api.Tests; public sealed class ArchiveBatchRequestValidationTests { [Fact] public void Mvc_validator_accepts_archive_record_metadata() { var services = new ServiceCollection(); services.AddLogging(); services.AddControllers().AddApplicationPart(typeof(ArchivesController).Assembly); using var provider = services.BuildServiceProvider(); var actionContext = new ActionContext( new DefaultHttpContext { RequestServices = provider }, new RouteData(), new ActionDescriptor(), new ModelStateDictionary()); var exception = Record.Exception(() => provider.GetRequiredService() .Validate(actionContext, null, string.Empty, new ArchiveBatchRequest([Guid.NewGuid()], true, "学期已结束"))); Assert.Null(exception); Assert.True(actionContext.ModelState.IsValid); } [Fact] public void Validation_metadata_is_attached_to_record_constructor_parameters() { var constructor = Assert.Single(typeof(ArchiveBatchRequest).GetConstructors()); var parameters = constructor.GetParameters(); Assert.Contains(parameters[0].GetCustomAttributes(), x => x is RequiredAttribute); Assert.Contains(parameters[0].GetCustomAttributes(), x => x is MinLengthAttribute { Length: 1 }); Assert.Contains(parameters[0].GetCustomAttributes(), x => x is MaxLengthAttribute { Length: 100 }); Assert.Contains(parameters[2].GetCustomAttributes(), x => x is MaxLengthAttribute { Length: 500 }); Assert.Empty(typeof(ArchiveBatchRequest).GetProperty(nameof(ArchiveBatchRequest.Ids))! .GetCustomAttributes()); Assert.Empty(typeof(ArchiveBatchRequest).GetProperty(nameof(ArchiveBatchRequest.Reason))! .GetCustomAttributes()); } }