1234 lines
47 KiB
C#
1234 lines
47 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.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
using Microsoft.AspNetCore.Mvc.Razor;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
|
|
using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
|
|
using Microsoft.Extensions.Options;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.Mvc.ApplicationModels
|
|
{
|
|
public class DefaultPageApplicationModelProviderTest
|
|
{
|
|
[Fact]
|
|
public void OnProvidersExecuting_ThrowsIfPageDoesNotDeriveFromValidBaseType()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(InvalidPageWithWrongBaseClass).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act & Assert
|
|
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
|
|
|
// Assert
|
|
Assert.Equal(
|
|
$"The type '{typeInfo.FullName}' is not a valid page. A page must inherit from '{typeof(PageBase).FullName}'.",
|
|
ex.Message);
|
|
}
|
|
|
|
private class InvalidPageWithWrongBaseClass : RazorPageBase
|
|
{
|
|
public override void BeginContext(int position, int length, bool isLiteral)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override void EndContext()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override void EnsureRenderedBodyOrSections()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public override Task ExecuteAsync()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_ThrowsIfModelPropertyDoesNotExistOnPage()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithoutModelProperty).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act & Assert
|
|
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
|
|
|
// Assert
|
|
Assert.Equal(
|
|
$"The type '{typeInfo.FullName}' is not a valid page. A page must define a public, non-static 'Model' property.",
|
|
ex.Message);
|
|
}
|
|
|
|
private class PageWithoutModelProperty : PageBase
|
|
{
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_ThrowsIfModelPropertyIsNotPublic()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithNonVisibleModel).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act & Assert
|
|
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
|
|
|
// Assert
|
|
Assert.Equal(
|
|
$"The type '{typeInfo.FullName}' is not a valid page. A page must define a public, non-static 'Model' property.",
|
|
ex.Message);
|
|
}
|
|
|
|
private class PageWithNonVisibleModel : PageBase
|
|
{
|
|
private object Model => null;
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_ThrowsIfModelPropertyIsStatic()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithStaticModel).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act & Assert
|
|
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
|
|
|
// Assert
|
|
Assert.Equal(
|
|
$"The type '{typeInfo.FullName}' is not a valid page. A page must define a public, non-static 'Model' property.",
|
|
ex.Message);
|
|
}
|
|
|
|
private class PageWithStaticModel : PageBase
|
|
{
|
|
public static object Model => null;
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversPropertiesFromPage_IfModelTypeDoesNotHaveAttribute()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithModelWithoutPageModelAttribute).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
var propertiesOnPage = context.PageApplicationModel.HandlerProperties
|
|
.Where(p => p.PropertyInfo.DeclaringType.GetTypeInfo() == typeInfo);
|
|
Assert.Collection(
|
|
propertiesOnPage.OrderBy(p => p.PropertyName),
|
|
property =>
|
|
{
|
|
Assert.Equal(typeInfo.GetProperty(nameof(PageWithModelWithoutPageModelAttribute.Model)), property.PropertyInfo);
|
|
Assert.Equal(nameof(PageWithModelWithoutPageModelAttribute.Model), property.PropertyName);
|
|
},
|
|
property =>
|
|
{
|
|
Assert.Equal(typeInfo.GetProperty(nameof(PageWithModelWithoutPageModelAttribute.Property1)), property.PropertyInfo);
|
|
Assert.Null(property.BindingInfo);
|
|
Assert.Equal(nameof(PageWithModelWithoutPageModelAttribute.Property1), property.PropertyName);
|
|
},
|
|
property =>
|
|
{
|
|
Assert.Equal(typeInfo.GetProperty(nameof(PageWithModelWithoutPageModelAttribute.Property2)), property.PropertyInfo);
|
|
Assert.Equal(nameof(PageWithModelWithoutPageModelAttribute.Property2), property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
Assert.Equal(BindingSource.Path, property.BindingInfo.BindingSource);
|
|
});
|
|
}
|
|
|
|
private class PageWithModelWithoutPageModelAttribute : Page
|
|
{
|
|
public string Property1 { get; set; }
|
|
|
|
[FromRoute]
|
|
public object Property2 { get; set; }
|
|
|
|
public ModelWithoutPageModelAttribute Model => null;
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
private class ModelWithoutPageModelAttribute
|
|
{
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversPropertiesFromPageModel_IfModelHasAttribute()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithModelWithPageModelAttribute).GetTypeInfo();
|
|
var modelType = typeof(ModelWithPageModelAttribute);
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
Assert.Collection(
|
|
context.PageApplicationModel.HandlerProperties.OrderBy(p => p.PropertyName),
|
|
property =>
|
|
{
|
|
Assert.Equal(modelType.GetProperty(nameof(ModelWithPageModelAttribute.Property)), property.PropertyInfo);
|
|
Assert.Equal(nameof(ModelWithPageModelAttribute.Property), property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
Assert.Equal(BindingSource.Path, property.BindingInfo.BindingSource);
|
|
});
|
|
}
|
|
|
|
private class PageWithModelWithPageModelAttribute : Page
|
|
{
|
|
public string Property1 { get; set; }
|
|
|
|
[FromRoute]
|
|
public object Property2 { get; set; }
|
|
|
|
public ModelWithPageModelAttribute Model => null;
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
[PageModel]
|
|
private class ModelWithPageModelAttribute
|
|
{
|
|
[FromRoute]
|
|
public string Property { get; set; }
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversProperties_FromAllSubTypesThatDeclaresBindProperty()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(BindPropertyAttributeOnBaseModelPage).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
Assert.Collection(
|
|
context.PageApplicationModel.HandlerProperties.OrderBy(p => p.PropertyName).Where(p => p.BindingInfo != null),
|
|
property =>
|
|
{
|
|
var name = nameof(ModelLevel3.Property2);
|
|
Assert.Equal(typeof(ModelLevel3).GetProperty(name), property.PropertyInfo);
|
|
Assert.Equal(name, property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
},
|
|
property =>
|
|
{
|
|
var name = nameof(ModelLevel3.Property3);
|
|
Assert.Equal(typeof(ModelLevel3).GetProperty(name), property.PropertyInfo);
|
|
Assert.Equal(name, property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
});
|
|
}
|
|
|
|
private class BindPropertyAttributeOnBaseModelPage : Page
|
|
{
|
|
public ModelLevel3 Model => null;
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
private class ModelLevel1 : PageModel
|
|
{
|
|
public string Property1 { get; set; }
|
|
}
|
|
|
|
[BindProperties]
|
|
private class ModelLevel2 : ModelLevel1
|
|
{
|
|
public string Property2 { get; set; }
|
|
}
|
|
|
|
private class ModelLevel3 : ModelLevel2
|
|
{
|
|
public string Property3 { get; set; }
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversHandlersFromPage()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithModelWithoutHandlers).GetTypeInfo();
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
Assert.Collection(
|
|
context.PageApplicationModel.HandlerMethods.OrderBy(p => p.Name),
|
|
handler =>
|
|
{
|
|
var name = nameof(PageWithModelWithoutHandlers.OnGet);
|
|
Assert.Equal(typeInfo.GetMethod(name), handler.MethodInfo);
|
|
Assert.Equal(name, handler.Name);
|
|
Assert.Equal("Get", handler.HttpMethod);
|
|
Assert.Null(handler.HandlerName);
|
|
},
|
|
handler =>
|
|
{
|
|
var name = nameof(PageWithModelWithoutHandlers.OnPostAsync);
|
|
Assert.Equal(typeInfo.GetMethod(name), handler.MethodInfo);
|
|
Assert.Equal(name, handler.Name);
|
|
Assert.Equal("Post", handler.HttpMethod);
|
|
Assert.Null(handler.HandlerName);
|
|
},
|
|
handler =>
|
|
{
|
|
var name = nameof(PageWithModelWithoutHandlers.OnPostDeleteCustomerAsync);
|
|
Assert.Equal(typeInfo.GetMethod(name), handler.MethodInfo);
|
|
Assert.Equal(name, handler.Name);
|
|
Assert.Equal("Post", handler.HttpMethod);
|
|
Assert.Equal("DeleteCustomer", handler.HandlerName);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversPropertiesFromModel()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithModel).GetTypeInfo();
|
|
var modelType = typeof(TestPageModel);
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
Assert.Collection(
|
|
context.PageApplicationModel.HandlerProperties.OrderBy(p => p.PropertyName),
|
|
property =>
|
|
{
|
|
var name = nameof(TestPageModel.Property1);
|
|
Assert.Equal(modelType.GetProperty(name), property.PropertyInfo);
|
|
Assert.Null(property.BindingInfo);
|
|
Assert.Equal(name, property.PropertyName);
|
|
},
|
|
property =>
|
|
{
|
|
var name = nameof(TestPageModel.Property2);
|
|
Assert.Equal(modelType.GetProperty(name), property.PropertyInfo);
|
|
Assert.Equal(name, property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
Assert.Equal(BindingSource.Query, property.BindingInfo.BindingSource);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversBindingInfoFromHandler()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithBindPropertyModel).GetTypeInfo();
|
|
var modelType = typeof(ModelWithBindProperty);
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
Assert.Collection(
|
|
context.PageApplicationModel.HandlerProperties.OrderBy(p => p.PropertyName),
|
|
property =>
|
|
{
|
|
Assert.Equal(nameof(ModelWithBindProperty.Property1), property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
},
|
|
property =>
|
|
{
|
|
Assert.Equal(nameof(ModelWithBindProperty.Property2), property.PropertyName);
|
|
Assert.NotNull(property.BindingInfo);
|
|
Assert.Equal(BindingSource.Path, property.BindingInfo.BindingSource);
|
|
});
|
|
}
|
|
|
|
private class PageWithBindPropertyModel : PageBase
|
|
{
|
|
public ModelWithBindProperty Model => null;
|
|
|
|
public override Task ExecuteAsync() => null;
|
|
}
|
|
|
|
[BindProperties]
|
|
[PageModel]
|
|
private class ModelWithBindProperty
|
|
{
|
|
public string Property1 { get; set; }
|
|
|
|
[FromRoute]
|
|
public string Property2 { get; set; }
|
|
}
|
|
|
|
[Fact]
|
|
public void OnProvidersExecuting_DiscoversHandlersFromModel()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithModel).GetTypeInfo();
|
|
var modelType = typeof(TestPageModel);
|
|
var descriptor = new PageActionDescriptor();
|
|
var context = new PageApplicationModelProviderContext(descriptor, typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
Assert.NotNull(context.PageApplicationModel);
|
|
Assert.Collection(
|
|
context.PageApplicationModel.HandlerMethods.OrderBy(p => p.Name),
|
|
handler =>
|
|
{
|
|
var name = nameof(TestPageModel.OnGetUser);
|
|
Assert.Equal(modelType.GetMethod(name), handler.MethodInfo);
|
|
Assert.Equal(name, handler.Name);
|
|
Assert.Equal("Get", handler.HttpMethod);
|
|
Assert.Equal("User", handler.HandlerName);
|
|
});
|
|
}
|
|
|
|
// We want to test the 'empty' page has no bound properties, and no handler methods.
|
|
[Fact]
|
|
public void OnProvidersExecuting_EmptyPage()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(EmptyPage).GetTypeInfo();
|
|
var context = new PageApplicationModelProviderContext(new PageActionDescriptor(), typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
var pageModel = context.PageApplicationModel;
|
|
Assert.Empty(pageModel.HandlerProperties.Where(p => p.BindingInfo != null));
|
|
Assert.Empty(pageModel.HandlerMethods);
|
|
Assert.Same(typeof(EmptyPage).GetTypeInfo(), pageModel.HandlerType);
|
|
Assert.Same(typeof(EmptyPage).GetTypeInfo(), pageModel.ModelType);
|
|
Assert.Same(typeof(EmptyPage).GetTypeInfo(), pageModel.PageType);
|
|
}
|
|
|
|
// We want to test the 'empty' page and PageModel has no bound properties, and no handler methods.
|
|
[Fact]
|
|
public void OnProvidersExecuting_EmptyPageModel()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(EmptyPageWithPageModel).GetTypeInfo();
|
|
var context = new PageApplicationModelProviderContext(new PageActionDescriptor(), typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
var pageModel = context.PageApplicationModel;
|
|
Assert.Empty(pageModel.HandlerProperties.Where(p => p.BindingInfo != null));
|
|
Assert.Empty(pageModel.HandlerMethods);
|
|
Assert.Same(typeof(EmptyPageModel).GetTypeInfo(), pageModel.DeclaredModelType);
|
|
Assert.Same(typeof(EmptyPageModel).GetTypeInfo(), pageModel.ModelType);
|
|
Assert.Same(typeof(EmptyPageModel).GetTypeInfo(), pageModel.HandlerType);
|
|
Assert.Same(typeof(EmptyPageWithPageModel).GetTypeInfo(), pageModel.PageType);
|
|
}
|
|
|
|
private class EmptyPage : Page
|
|
{
|
|
// Copied from generated code
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<EmptyPage> Html { get; private set; }
|
|
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<EmptyPage> ViewData => null;
|
|
public EmptyPage Model => ViewData.Model;
|
|
|
|
public override Task ExecuteAsync()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
private class EmptyPageWithPageModel : Page
|
|
{
|
|
// Copied from generated code
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; }
|
|
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
|
|
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<EmptyPageModel> Html { get; private set; }
|
|
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<EmptyPageModel> ViewData => null;
|
|
public EmptyPageModel Model => ViewData.Model;
|
|
|
|
public override Task ExecuteAsync()
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
private class EmptyPageModel : PageModel
|
|
{
|
|
}
|
|
|
|
[Fact] // If the model has handler methods, we prefer those.
|
|
public void CreateDescriptor_FindsHandlerMethod_OnModel()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithHandlerThatGetsIgnored).GetTypeInfo();
|
|
var modelType = typeof(ModelWithHandler);
|
|
var context = new PageApplicationModelProviderContext(new PageActionDescriptor(), typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
var pageModel = context.PageApplicationModel;
|
|
Assert.Contains(
|
|
pageModel.HandlerProperties,
|
|
p => p.PropertyInfo == modelType.GetProperty(nameof(ModelWithHandler.BindMe)));
|
|
|
|
Assert.Collection(
|
|
pageModel.HandlerMethods,
|
|
p => Assert.Equal(modelType.GetMethod(nameof(ModelWithHandler.OnGet)), p.MethodInfo));
|
|
|
|
Assert.Same(typeof(ModelWithHandler).GetTypeInfo(), pageModel.HandlerType);
|
|
Assert.Same(typeof(ModelWithHandler).GetTypeInfo(), pageModel.ModelType);
|
|
Assert.Same(typeof(PageWithHandlerThatGetsIgnored).GetTypeInfo(), pageModel.PageType);
|
|
}
|
|
|
|
private class ModelWithHandler : PageModel
|
|
{
|
|
[ModelBinder]
|
|
public int BindMe { get; set; }
|
|
|
|
public void OnGet() { }
|
|
}
|
|
|
|
private class PageWithHandlerThatGetsIgnored : Page
|
|
{
|
|
public ModelWithHandler Model => null;
|
|
|
|
[ModelBinder]
|
|
public int IgnoreMe { get; set; }
|
|
|
|
public void OnPost() { }
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
[Fact] // If the model does not have the PageModelAttribute, we look at the page instead.
|
|
public void OnProvidersExecuting_FindsHandlerMethodOnPage_WhenModelIsNotAnnotatedWithPageModelAttribute()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithHandler).GetTypeInfo();
|
|
var context = new PageApplicationModelProviderContext(new PageActionDescriptor(), typeInfo);
|
|
|
|
// Act
|
|
provider.OnProvidersExecuting(context);
|
|
|
|
// Assert
|
|
var pageModel = context.PageApplicationModel;
|
|
var propertiesOnPage = pageModel.HandlerProperties
|
|
.Where(p => p.PropertyInfo.DeclaringType.GetTypeInfo() == typeInfo);
|
|
Assert.Collection(
|
|
propertiesOnPage.OrderBy(p => p.PropertyName),
|
|
p => Assert.Equal(typeInfo.GetProperty(nameof(PageWithHandler.BindMe)), p.PropertyInfo),
|
|
p => Assert.Equal(typeInfo.GetProperty(nameof(PageWithHandler.Model)), p.PropertyInfo));
|
|
|
|
Assert.Collection(
|
|
pageModel.HandlerMethods,
|
|
p => Assert.Equal(typeInfo.GetMethod(nameof(PageWithHandler.OnGet)), p.MethodInfo));
|
|
|
|
Assert.Same(typeof(PageWithHandler).GetTypeInfo(), pageModel.HandlerType);
|
|
Assert.Same(typeof(PocoModel).GetTypeInfo(), pageModel.ModelType);
|
|
Assert.Same(typeof(PageWithHandler).GetTypeInfo(), pageModel.PageType);
|
|
}
|
|
|
|
private class PageWithHandler : Page
|
|
{
|
|
public PocoModel Model => null;
|
|
|
|
[ModelBinder]
|
|
public int BindMe { get; set; }
|
|
|
|
public void OnGet() { }
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
private class PocoModel
|
|
{
|
|
// Just a plain ol' model, nothing to see here.
|
|
|
|
[ModelBinder]
|
|
public int IgnoreMe { get; set; }
|
|
|
|
public void OnGet() { }
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerMethods_DiscoversHandlersFromBaseType()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(InheritsMethods).GetTypeInfo();
|
|
var baseType = typeof(TestSetPageModel);
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Collection(
|
|
handlerMethods.OrderBy(h => h.MethodInfo.DeclaringType.Name).ThenBy(h => h.MethodInfo.Name),
|
|
handler =>
|
|
{
|
|
Assert.Equal(nameof(InheritsMethods.OnGet), handler.MethodInfo.Name);
|
|
Assert.Equal(typeInfo, handler.MethodInfo.DeclaringType.GetTypeInfo());
|
|
},
|
|
handler =>
|
|
{
|
|
Assert.Equal(nameof(TestSetPageModel.OnGet), handler.MethodInfo.Name);
|
|
Assert.Equal(baseType, handler.MethodInfo.DeclaringType);
|
|
},
|
|
handler =>
|
|
{
|
|
Assert.Equal(nameof(TestSetPageModel.OnPost), handler.MethodInfo.Name);
|
|
Assert.Equal(baseType, handler.MethodInfo.DeclaringType);
|
|
});
|
|
}
|
|
|
|
private class TestSetPageModel
|
|
{
|
|
public void OnGet()
|
|
{
|
|
}
|
|
|
|
public void OnPost()
|
|
{
|
|
}
|
|
}
|
|
|
|
private class InheritsMethods : TestSetPageModel
|
|
{
|
|
public new void OnGet()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerMethods_IgnoresNonPublicMethods()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(ProtectedModel).GetTypeInfo();
|
|
var baseType = typeof(TestSetPageModel);
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Empty(handlerMethods);
|
|
}
|
|
|
|
private class ProtectedModel
|
|
{
|
|
protected void OnGet()
|
|
{
|
|
}
|
|
|
|
private void OnPost()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerMethods_IgnoreGenericTypeParameters()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(GenericClassModel).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Empty(handlerMethods);
|
|
}
|
|
|
|
private class GenericClassModel
|
|
{
|
|
public void OnGet<T>()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerMethods_IgnoresStaticMethods()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageModelWithStaticHandler).GetTypeInfo();
|
|
var expected = typeInfo.GetMethod(nameof(PageModelWithStaticHandler.OnGet), BindingFlags.Public | BindingFlags.Instance);
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Collection(
|
|
handlerMethods,
|
|
handler => Assert.Same(expected, handler.MethodInfo));
|
|
}
|
|
|
|
private class PageModelWithStaticHandler
|
|
{
|
|
public static void OnGet(string name)
|
|
{
|
|
}
|
|
|
|
public void OnGet()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerMethods_IgnoresAbstractMethods()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageModelWithAbstractMethod).GetTypeInfo();
|
|
var expected = typeInfo.GetMethod(nameof(PageModelWithAbstractMethod.OnGet), BindingFlags.Public | BindingFlags.Instance);
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Collection(
|
|
handlerMethods,
|
|
handler => Assert.Same(expected, handler.MethodInfo));
|
|
}
|
|
|
|
private abstract class PageModelWithAbstractMethod
|
|
{
|
|
public abstract void OnPost(string name);
|
|
|
|
public void OnGet()
|
|
{
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerMethods_IgnoresMethodWithNonHandlerAttribute()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithNonHandlerMethod).GetTypeInfo();
|
|
var expected = typeInfo.GetMethod(nameof(PageWithNonHandlerMethod.OnGet), BindingFlags.Public | BindingFlags.Instance);
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Collection(
|
|
handlerMethods,
|
|
handler => Assert.Same(expected, handler.MethodInfo));
|
|
}
|
|
|
|
private class PageWithNonHandlerMethod
|
|
{
|
|
[NonHandler]
|
|
public void OnPost(string name) { }
|
|
|
|
public void OnGet()
|
|
{
|
|
}
|
|
}
|
|
|
|
// There are more tests for the parsing elsewhere, this is just testing that it's wired
|
|
// up to the model.
|
|
[Fact]
|
|
public void CreateHandlerModel_ParsesMethod()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageModelWithHandlerNames).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
Assert.Collection(
|
|
handlerMethods.OrderBy(h => h.MethodInfo.Name),
|
|
handler =>
|
|
{
|
|
Assert.Same(typeInfo.GetMethod(nameof(PageModelWithHandlerNames.OnPutDeleteAsync)), handler.MethodInfo);
|
|
Assert.Equal("Put", handler.HttpMethod);
|
|
Assert.Equal("Delete", handler.HandlerName);
|
|
});
|
|
}
|
|
|
|
private class PageModelWithHandlerNames
|
|
{
|
|
public void OnPutDeleteAsync()
|
|
{
|
|
}
|
|
|
|
public void Foo() // This isn't a valid handler name.
|
|
{
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateHandlerMethods_AddsParameterDescriptors()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(PageWithHandlerParameters).GetTypeInfo();
|
|
var expected = typeInfo.GetMethod(nameof(PageWithHandlerParameters.OnPost));
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
var handler = Assert.Single(handlerMethods);
|
|
|
|
Assert.Collection(
|
|
handler.Parameters,
|
|
p =>
|
|
{
|
|
Assert.NotNull(p.ParameterInfo);
|
|
Assert.Equal(typeof(string), p.ParameterInfo.ParameterType);
|
|
Assert.Equal("name", p.ParameterName);
|
|
},
|
|
p =>
|
|
{
|
|
Assert.NotNull(p.ParameterInfo);
|
|
Assert.Equal(typeof(int), p.ParameterInfo.ParameterType);
|
|
Assert.Equal("id", p.ParameterName);
|
|
Assert.Equal("personId", p.BindingInfo.BinderModelName);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateHandlerMethods_WithLegacyValidationBehavior_AddsParameterDescriptors()
|
|
{
|
|
// Arrange
|
|
var provider = new DefaultPageApplicationModelProvider(
|
|
TestModelMetadataProvider.CreateDefaultProvider(),
|
|
Options.Create(new MvcOptions { AllowValidatingTopLevelNodes = false }),
|
|
Options.Create(new RazorPagesOptions()));
|
|
var typeInfo = typeof(PageWithHandlerParameters).GetTypeInfo();
|
|
var expected = typeInfo.GetMethod(nameof(PageWithHandlerParameters.OnPost));
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerMethods(pageModel);
|
|
|
|
// Assert
|
|
var handlerMethods = pageModel.HandlerMethods;
|
|
var handler = Assert.Single(handlerMethods);
|
|
|
|
Assert.Collection(
|
|
handler.Parameters,
|
|
p =>
|
|
{
|
|
Assert.NotNull(p.ParameterInfo);
|
|
Assert.Equal(typeof(string), p.ParameterInfo.ParameterType);
|
|
Assert.Equal("name", p.ParameterName);
|
|
},
|
|
p =>
|
|
{
|
|
Assert.NotNull(p.ParameterInfo);
|
|
Assert.Equal(typeof(int), p.ParameterInfo.ParameterType);
|
|
Assert.Equal("id", p.ParameterName);
|
|
Assert.Equal("personId", p.BindingInfo.BinderModelName);
|
|
});
|
|
}
|
|
|
|
private class PageWithHandlerParameters
|
|
{
|
|
public void OnPost(string name, [ModelBinder(Name = "personId")] int id) { }
|
|
}
|
|
|
|
// We're using PropertyHelper from Common to find the properties here, which implements
|
|
// out standard set of semantics for properties that the framework interacts with.
|
|
//
|
|
// One of the desirable consequences of that is we only find 'visible' properties. We're not
|
|
// retesting all of the details of PropertyHelper here, just the visibility part as a quick check
|
|
// that we're using PropertyHelper as expected.
|
|
[Fact]
|
|
public void PopulateHandlerProperties_UsesPropertyHelpers_ToFindProperties()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(HidesAProperty).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerProperties(pageModel);
|
|
|
|
// Assert
|
|
var properties = pageModel.HandlerProperties;
|
|
Assert.Collection(
|
|
properties,
|
|
p =>
|
|
{
|
|
Assert.Equal(typeof(HidesAProperty).GetTypeInfo(), p.PropertyInfo.DeclaringType.GetTypeInfo());
|
|
});
|
|
}
|
|
|
|
private class HasAHiddenProperty
|
|
{
|
|
[BindProperty]
|
|
public int Property { get; set; }
|
|
}
|
|
|
|
private class HidesAProperty : HasAHiddenProperty
|
|
{
|
|
[BindProperty]
|
|
public new int Property { get; set; }
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateHandlerProperties_SupportsGet_OnProperty()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(ModelSupportsGetOnProperty).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, new object[0]);
|
|
|
|
// Act
|
|
provider.PopulateHandlerProperties(pageModel);
|
|
|
|
// Assert
|
|
var properties = pageModel.HandlerProperties;
|
|
Assert.Collection(
|
|
properties.OrderBy(p => p.PropertyName),
|
|
p =>
|
|
{
|
|
Assert.Equal(typeInfo.GetProperty(nameof(ModelSupportsGetOnProperty.Property)), p.PropertyInfo);
|
|
Assert.NotNull(p.BindingInfo.RequestPredicate);
|
|
Assert.True(p.BindingInfo.RequestPredicate(new ActionContext
|
|
{
|
|
HttpContext = new DefaultHttpContext
|
|
{
|
|
Request =
|
|
{
|
|
Method ="GET",
|
|
}
|
|
}
|
|
}));
|
|
});
|
|
}
|
|
|
|
private class ModelSupportsGetOnProperty
|
|
{
|
|
[BindProperty(SupportsGet = true)]
|
|
public int Property { get; set; }
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("Foo")]
|
|
[InlineData("On")]
|
|
[InlineData("OnAsync")]
|
|
[InlineData("Async")]
|
|
public void TryParseHandler_ParsesHandlerNames_InvalidData(string methodName)
|
|
{
|
|
// Act
|
|
var result = DefaultPageApplicationModelProvider.TryParseHandlerMethod(methodName, out var httpMethod, out var handler);
|
|
|
|
// Assert
|
|
Assert.False(result);
|
|
Assert.Null(httpMethod);
|
|
Assert.Null(handler);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("OnG", "G", null)]
|
|
[InlineData("OnGAsync", "G", null)]
|
|
[InlineData("OnPOST", "P", "OST")]
|
|
[InlineData("OnPOSTAsync", "P", "OST")]
|
|
[InlineData("OnDeleteFoo", "Delete", "Foo")]
|
|
[InlineData("OnDeleteFooAsync", "Delete", "Foo")]
|
|
[InlineData("OnMadeupLongHandlerName", "Madeup", "LongHandlerName")]
|
|
[InlineData("OnMadeupLongHandlerNameAsync", "Madeup", "LongHandlerName")]
|
|
public void TryParseHandler_ParsesHandlerNames_ValidData(string methodName, string expectedHttpMethod, string expectedHandler)
|
|
{
|
|
// Arrange
|
|
|
|
// Act
|
|
var result = DefaultPageApplicationModelProvider.TryParseHandlerMethod(methodName, out var httpMethod, out var handler);
|
|
|
|
// Assert
|
|
Assert.True(result);
|
|
Assert.Equal(expectedHttpMethod, httpMethod);
|
|
Assert.Equal(expectedHandler, handler);
|
|
}
|
|
|
|
private class PageWithModelWithoutHandlers : Page
|
|
{
|
|
public ModelWithoutHandler Model { get; }
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
|
|
public void OnGet() { }
|
|
|
|
public void OnPostAsync() { }
|
|
|
|
public void OnPostDeleteCustomerAsync() { }
|
|
|
|
public class ModelWithoutHandler
|
|
{
|
|
}
|
|
}
|
|
|
|
private class PageWithModel : Page
|
|
{
|
|
public TestPageModel Model { get; }
|
|
|
|
public override Task ExecuteAsync() => throw new NotImplementedException();
|
|
}
|
|
|
|
[PageModel]
|
|
private class TestPageModel
|
|
{
|
|
public string Property1 { get; set; }
|
|
|
|
[FromQuery]
|
|
public string Property2 { get; set; }
|
|
|
|
public void OnGetUser() { }
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateFilters_With21CompatBehavior_DoesNotAddDisallowOptionsRequestsPageFilter()
|
|
{
|
|
// Arrange
|
|
var provider = new DefaultPageApplicationModelProvider(
|
|
TestModelMetadataProvider.CreateDefaultProvider(),
|
|
Options.Create(new MvcOptions()),
|
|
Options.Create(new RazorPagesOptions()));
|
|
var typeInfo = typeof(object).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, typeInfo.GetCustomAttributes(inherit: true));
|
|
|
|
// Act
|
|
provider.PopulateFilters(pageModel);
|
|
|
|
// Assert
|
|
Assert.Empty(pageModel.Filters);
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateFilters_AddsDisallowOptionsRequestsPageFilter()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(object).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, typeInfo.GetCustomAttributes(inherit: true));
|
|
|
|
// Act
|
|
provider.PopulateFilters(pageModel);
|
|
|
|
// Assert
|
|
Assert.Collection(
|
|
pageModel.Filters,
|
|
filter => Assert.IsType<HandleOptionsRequestsPageFilter>(filter));
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateFilters_AddsIFilterMetadataAttributesToModel()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(FilterModel).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, typeInfo.GetCustomAttributes(inherit: true));
|
|
|
|
// Act
|
|
provider.PopulateFilters(pageModel);
|
|
|
|
// Assert
|
|
Assert.Collection(
|
|
pageModel.Filters,
|
|
filter => Assert.IsType<TypeFilterAttribute>(filter),
|
|
filter => Assert.IsType<HandleOptionsRequestsPageFilter>(filter));
|
|
}
|
|
|
|
[PageModel]
|
|
[Serializable]
|
|
[TypeFilter(typeof(object))]
|
|
private class FilterModel
|
|
{
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateFilters_AddsPageHandlerPageFilter_IfPageImplementsIAsyncPageFilter()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(ModelImplementingAsyncPageFilter).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, typeInfo.GetCustomAttributes(inherit: true));
|
|
|
|
// Act
|
|
provider.PopulateFilters(pageModel);
|
|
|
|
// Assert
|
|
Assert.Collection(
|
|
pageModel.Filters,
|
|
filter => Assert.IsType<PageHandlerPageFilter>(filter),
|
|
filter => Assert.IsType<HandleOptionsRequestsPageFilter>(filter));
|
|
}
|
|
|
|
private class ModelImplementingAsyncPageFilter : IAsyncPageFilter
|
|
{
|
|
public Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateFilters_AddsPageHandlerPageFilter_IfPageImplementsIPageFilter()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(ModelImplementingPageFilter).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, typeInfo.GetCustomAttributes(inherit: true));
|
|
|
|
// Act
|
|
provider.PopulateFilters(pageModel);
|
|
|
|
// Assert
|
|
Assert.Collection(
|
|
pageModel.Filters,
|
|
filter => Assert.IsType<PageHandlerPageFilter>(filter),
|
|
filter => Assert.IsType<HandleOptionsRequestsPageFilter>(filter));
|
|
}
|
|
|
|
private class ModelImplementingPageFilter : IPageFilter
|
|
{
|
|
public void OnPageHandlerExecuted(PageHandlerExecutedContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void OnPageHandlerExecuting(PageHandlerExecutingContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void OnPageHandlerSelected(PageHandlerSelectedContext context)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void PopulateFilters_AddsPageHandlerPageFilter_ForModelDerivingFromTypeImplementingPageFilter()
|
|
{
|
|
// Arrange
|
|
var provider = CreateProvider();
|
|
var typeInfo = typeof(DerivedFromPageModel).GetTypeInfo();
|
|
var pageModel = new PageApplicationModel(new PageActionDescriptor(), typeInfo, typeInfo.GetCustomAttributes(inherit: true));
|
|
|
|
// Act
|
|
provider.PopulateFilters(pageModel);
|
|
|
|
// Assert
|
|
Assert.Collection(
|
|
pageModel.Filters,
|
|
filter => Assert.IsType<ServiceFilterAttribute>(filter),
|
|
filter => Assert.IsType<PageHandlerPageFilter>(filter),
|
|
filter => Assert.IsType<HandleOptionsRequestsPageFilter>(filter));
|
|
}
|
|
|
|
[ServiceFilter(typeof(IServiceProvider))]
|
|
private class DerivedFromPageModel : PageModel { }
|
|
|
|
private static DefaultPageApplicationModelProvider CreateProvider()
|
|
{
|
|
return new DefaultPageApplicationModelProvider(
|
|
TestModelMetadataProvider.CreateDefaultProvider(),
|
|
Options.Create(new MvcOptions { AllowValidatingTopLevelNodes = true }),
|
|
Options.Create(new RazorPagesOptions { AllowDefaultHandlingForOptionsRequests = true }));
|
|
}
|
|
}
|
|
}
|