public void GetViewStartFactories_FindsFullHierarchy() { // Arrange var descriptor = new PageActionDescriptor() { RelativePath = "/Pages/Level1/Level2/Index.cshtml", FilterDescriptors = new FilterDescriptor[0], ViewEnginePath = "/Pages/Level1/Level2/Index.cshtml" }; var compiledPageDescriptor = new CompiledPageActionDescriptor(descriptor) { PageTypeInfo = typeof(object).GetTypeInfo(), }; var loader = new Mock <PageLoader>(); loader .Setup(l => l.LoadAsync(It.IsAny <PageActionDescriptor>(), It.IsAny <EndpointMetadataCollection>())) .ReturnsAsync(compiledPageDescriptor); var mock = new Mock <IRazorPageFactoryProvider>(MockBehavior.Strict); mock .Setup(p => p.CreateFactory("/Pages/Level1/Level2/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null)) .Verifiable(); mock .Setup(p => p.CreateFactory("/Pages/Level1/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null)) .Verifiable(); mock .Setup(p => p.CreateFactory("/Pages/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null)) .Verifiable(); mock .Setup(p => p.CreateFactory("/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null)) .Verifiable(); var razorPageFactoryProvider = mock.Object; var invokerProvider = CreateInvokerProvider( loader.Object, razorPageFactoryProvider: razorPageFactoryProvider); // Act var factories = invokerProvider.Cache.GetViewStartFactories(compiledPageDescriptor); // Assert mock.Verify(); }
public async Task LoadAsync_CreatesEndpoint_WithRoute() { // Arrange var descriptor = new PageActionDescriptor() { AttributeRouteInfo = new AttributeRouteInfo() { Template = "/test", }, }; var transformer = new Mock <RoutePatternTransformer>(); transformer .Setup(t => t.SubstituteRequiredValues(It.IsAny <RoutePattern>(), It.IsAny <object>())) .Returns <RoutePattern, object>((p, v) => p); var compilerProvider = GetCompilerProvider(); var mvcOptions = Options.Create(new MvcOptions()); var endpointFactory = new PublicActionEndpointFactory(transformer.Object); var provider = new Mock <IPageApplicationModelProvider>(); var pageApplicationModel = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()); provider.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Null(c.PageApplicationModel); c.PageApplicationModel = pageApplicationModel; }) .Verifiable(); var providers = new[] { provider.Object, }; var loader = new RuntimeRazorPageLoader( providers, compilerProvider, endpointFactory, RazorPagesOptions, mvcOptions); // Act var result = await loader.LoadAsync(descriptor); // Assert Assert.NotNull(result.Endpoint); }
private async Task <CompiledPageActionDescriptor> LoadAsyncCore(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata) { var viewDescriptor = await Compiler.CompileAsync(actionDescriptor.RelativePath); var context = new PageApplicationModelProviderContext(actionDescriptor, viewDescriptor.Type.GetTypeInfo()); for (var i = 0; i < _applicationModelProviders.Length; i++) { _applicationModelProviders[i].OnProvidersExecuting(context); } for (var i = _applicationModelProviders.Length - 1; i >= 0; i--) { _applicationModelProviders[i].OnProvidersExecuted(context); } ApplyConventions(_conventions, context.PageApplicationModel); var compiled = PublicCompiledPageActionDescriptorBuilder.Build(context.PageApplicationModel, _globalFilters); // We need to create an endpoint for routing to use and attach it to the CompiledPageActionDescriptor... // routing for pages is two-phase. First we perform routing using the route info - we can do this without // compiling/loading the page. Then once we have a match we load the page and we can create an endpoint // with all of the information we get from the compiled action descriptor. var endpoints = new List <Endpoint>(); _endpointFactory.AddEndpoints( endpoints, routeNames: new HashSet <string>(StringComparer.OrdinalIgnoreCase), action: compiled, routes: Array.Empty <PublicConventionalRouteEntry>(), conventions: new Action <EndpointBuilder>[] { b => { // Metadata from PageActionDescriptor is less significant than the one discovered from the compiled type. // Consequently, we'll insert it at the beginning. for (var i = endpointMetadata.Count - 1; i >= 0; i--) { b.Metadata.Insert(0, endpointMetadata[i]); } }, }, createInertEndpoints: false); // In some test scenarios there's no route so the endpoint isn't created. This is fine because // it won't happen for real. compiled.Endpoint = endpoints.SingleOrDefault(); return(compiled); }
public void CreateHandlerMethods_CopiesParameterDescriptorsFromParameterModel() { // Arrange var actionDescriptor = new PageActionDescriptor(); var handlerTypeInfo = typeof(HandlerWithParameters).GetTypeInfo(); var handlerMethod = handlerTypeInfo.GetMethod(nameof(HandlerWithParameters.OnPost)); var parameters = handlerMethod.GetParameters(); var parameterModel1 = new PageParameterModel(parameters[0], new object[0]) { ParameterName = "test-name" }; var parameterModel2 = new PageParameterModel(parameters[1], new object[0]) { BindingInfo = new BindingInfo(), }; var handlerModel = new PageHandlerModel(handlerMethod, new object[0]) { Parameters = { parameterModel1, parameterModel2, } }; var pageApplicationModel = new PageApplicationModel(actionDescriptor, handlerTypeInfo, new object[0]) { HandlerMethods = { handlerModel, } }; // Act var handlerDescriptors = CompiledPageActionDescriptorBuilder.CreateHandlerMethods(pageApplicationModel); // Assert Assert.Collection( Assert.Single(handlerDescriptors).Parameters, p => { Assert.Equal(parameters[0], p.ParameterInfo); Assert.Equal(typeof(string), p.ParameterType); Assert.Equal(parameterModel1.ParameterName, p.Name); }, p => { Assert.Equal(parameters[1], p.ParameterInfo); Assert.Equal(typeof(int), p.ParameterType); Assert.Same(parameterModel2.BindingInfo, p.BindingInfo); }); }
public void OnProvidersExecuting_CachesEntries() { // Arrange var descriptor = new PageActionDescriptor { RelativePath = "Path1", FilterDescriptors = new FilterDescriptor[0], }; var loader = new Mock <IPageLoader>(); loader .Setup(l => l.Load(It.IsAny <PageActionDescriptor>())) .Returns(CreateCompiledPageActionDescriptor(descriptor)); var invokerProvider = CreateInvokerProvider( loader.Object, CreateActionDescriptorCollection(descriptor)); var context = new ActionInvokerProviderContext(new ActionContext { ActionDescriptor = descriptor, HttpContext = new DefaultHttpContext(), RouteData = new RouteData(), }); // Act - 1 invokerProvider.OnProvidersExecuting(context); // Assert - 1 Assert.NotNull(context.Result); var actionInvoker = Assert.IsType <PageActionInvoker>(context.Result); var entry1 = actionInvoker.CacheEntry; // Act - 2 context = new ActionInvokerProviderContext(new ActionContext { ActionDescriptor = descriptor, HttpContext = new DefaultHttpContext(), RouteData = new RouteData(), }); invokerProvider.OnProvidersExecuting(context); // Assert - 2 Assert.NotNull(context.Result); actionInvoker = Assert.IsType <PageActionInvoker>(context.Result); var entry2 = actionInvoker.CacheEntry; Assert.Same(entry1, entry2); }
public void GetViewStartFactories_ReturnsFactoriesForFilesThatDoNotExistInProject() { // The factory provider might have access to _ViewStarts for files that do not exist on disk \ RazorProject. // This test verifies that we query the factory provider correctly. // Arrange var descriptor = new PageActionDescriptor() { RelativePath = "/Views/Deeper/Index.cshtml", FilterDescriptors = new FilterDescriptor[0], ViewEnginePath = "/Views/Deeper/Index.cshtml" }; var loader = new Mock <IPageLoader>(); loader .Setup(l => l.Load(It.IsAny <PageActionDescriptor>())) .Returns(CreateCompiledPageActionDescriptor(descriptor, typeof(TestPageModel))); var pageFactory = new Mock <IRazorPageFactoryProvider>(); pageFactory .Setup(f => f.CreateFactory("/Views/Deeper/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null)); pageFactory .Setup(f => f.CreateFactory("/Views/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), razorPageFactory: null)); pageFactory .Setup(f => f.CreateFactory("/_ViewStart.cshtml")) .Returns(new RazorPageFactoryResult(new CompiledViewDescriptor(), () => null)); // No files var fileProvider = new TestFileProvider(); var razorProject = new TestRazorProject(fileProvider, _hostingEnvironment); var invokerProvider = CreateInvokerProvider( loader.Object, CreateActionDescriptorCollection(descriptor), pageProvider: null, modelProvider: null, razorPageFactoryProvider: pageFactory.Object, razorProject: razorProject); var compiledDescriptor = CreateCompiledPageActionDescriptor(descriptor); // Act var factories = invokerProvider.GetViewStartFactories(compiledDescriptor).ToList(); // Assert Assert.Equal(2, factories.Count); }
public void CreateDescriptor_CopiesPropertiesFromPageApplicationModel() { // Arrange var actionDescriptor = new PageActionDescriptor { ActionConstraints = new List <IActionConstraintMetadata>(), AttributeRouteInfo = new AttributeRouteInfo(), FilterDescriptors = new List <FilterDescriptor>(), RelativePath = "/Foo", RouteValues = new Dictionary <string, string>(), ViewEnginePath = "/Pages/Foo", }; var handlerTypeInfo = typeof(TestModel).GetTypeInfo(); var pageApplicationModel = new PageApplicationModel(actionDescriptor, typeof(TestModel).GetTypeInfo(), handlerTypeInfo, new object[0]) { PageType = typeof(TestPage).GetTypeInfo(), ModelType = typeof(TestModel).GetTypeInfo(), Filters = { Mock.Of <IFilterMetadata>(), Mock.Of <IFilterMetadata>(), }, HandlerMethods = { new PageHandlerModel(handlerTypeInfo.GetMethod(nameof(TestModel.OnGet)), new object[0]), }, HandlerProperties = { new PagePropertyModel(handlerTypeInfo.GetProperty(nameof(TestModel.Property)), new object[0]) { BindingInfo = new BindingInfo(), }, } }; var globalFilters = new FilterCollection(); // Act var actual = CompiledPageActionDescriptorBuilder.Build(pageApplicationModel, globalFilters); // Assert Assert.Same(pageApplicationModel.PageType, actual.PageTypeInfo); Assert.Same(pageApplicationModel.DeclaredModelType, actual.DeclaredModelTypeInfo); Assert.Same(pageApplicationModel.ModelType, actual.ModelTypeInfo); Assert.Same(pageApplicationModel.HandlerType, actual.HandlerTypeInfo); Assert.Same(pageApplicationModel.Properties, actual.Properties); Assert.Equal(pageApplicationModel.Filters, actual.FilterDescriptors.Select(f => f.Filter)); Assert.Equal(pageApplicationModel.HandlerMethods.Select(p => p.MethodInfo), actual.HandlerMethods.Select(p => p.MethodInfo)); Assert.Equal(pageApplicationModel.HandlerProperties.Select(p => p.PropertyName), actual.BoundProperties.Select(p => p.Name)); }
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); }
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); }
/// <summary> /// Initializes a new instance of <see cref="PageApplicationModel"/>. /// </summary> public PageApplicationModel( PageActionDescriptor actionDescriptor, TypeInfo handlerType, IReadOnlyList <object> handlerAttributes) { ActionDescriptor = actionDescriptor ?? throw new ArgumentNullException(nameof(actionDescriptor)); HandlerType = handlerType; Filters = new List <IFilterMetadata>(); Properties = new CopyOnWriteDictionary <object, object>( actionDescriptor.Properties, EqualityComparer <object> .Default); HandlerMethods = new List <PageHandlerModel>(); HandlerProperties = new List <PagePropertyModel>(); HandlerTypeAttributes = handlerAttributes; }
public void SignOutNoScheme_SignsOutDefaultCookiesAndDefaultOpenIDConnectAADAzureADSchemesAsync() { // Arrange var options = new AzureADOptions() { CookieSchemeName = AzureADDefaults.CookieScheme, OpenIdConnectSchemeName = AzureADDefaults.OpenIdScheme }; var controllerContext = CreateControllerContext( CreateAuthenticatedPrincipal(AzureADDefaults.AuthenticationScheme)); var descriptor = new PageActionDescriptor() { AttributeRouteInfo = new AttributeRouteInfo() { Template = "/Account/SignedOut" } }; var controller = new AccountController(new OptionsMonitor(AzureADDefaults.AuthenticationScheme, options)) { Url = new TestUrlHelper( controllerContext.HttpContext, new RouteData(), descriptor, "/Account/SignedOut", "https://localhost/Account/SignedOut"), ControllerContext = new ControllerContext() { HttpContext = controllerContext.HttpContext } }; controller.Request.Scheme = "https"; // Act var result = controller.SignOut(null); // Assert var signOut = Assert.IsAssignableFrom <SignOutResult>(result); Assert.Equal(new[] { AzureADDefaults.CookieScheme, AzureADDefaults.OpenIdScheme }, signOut.AuthenticationSchemes); Assert.NotNull(signOut.Properties.RedirectUri); Assert.Equal("https://localhost/Account/SignedOut", signOut.Properties.RedirectUri); }
public void CreateDescriptor_AddsGlobalFiltersWithTheRightScope() { // Arrange var actionDescriptor = new PageActionDescriptor { ActionConstraints = new List <IActionConstraintMetadata>(), AttributeRouteInfo = new AttributeRouteInfo(), FilterDescriptors = new List <FilterDescriptor>(), RelativePath = "/Foo", RouteValues = new Dictionary <string, string>(), ViewEnginePath = "/Pages/Foo", }; var handlerTypeInfo = typeof(TestModel).GetTypeInfo(); var pageApplicationModel = new PageApplicationModel(actionDescriptor, handlerTypeInfo, new object[0]) { PageType = typeof(TestPage).GetTypeInfo(), ModelType = typeof(TestModel).GetTypeInfo(), Filters = { Mock.Of <IFilterMetadata>(), }, }; var globalFilters = new FilterCollection { Mock.Of <IFilterMetadata>(), }; // Act var compiledPageActionDescriptor = CompiledPageActionDescriptorBuilder.Build(pageApplicationModel, globalFilters); // Assert Assert.Collection( compiledPageActionDescriptor.FilterDescriptors, filterDescriptor => { Assert.Same(globalFilters[0], filterDescriptor.Filter); Assert.Equal(FilterScope.Global, filterDescriptor.Scope); }, filterDescriptor => { Assert.Same(pageApplicationModel.Filters[0], filterDescriptor.Filter); Assert.Equal(FilterScope.Action, filterDescriptor.Scope); }); }
public async Task SignOutProvidedScheme_SignsOutCustomCookiesAndCustomOpenIDConnectAADAzureADB2CSchemesAsync() { // Arrange var options = new AzureADB2COptions() { CookieSchemeName = "Cookie", OpenIdConnectSchemeName = "OpenID" }; var controllerContext = CreateControllerContext( CreateAuthenticatedPrincipal(AzureADB2CDefaults.AuthenticationScheme)); var descriptor = new PageActionDescriptor() { AttributeRouteInfo = new AttributeRouteInfo() { Template = "/Account/SignedOut" } }; var controller = new AccountController(new OptionsMonitor("Custom", options)) { Url = new TestUrlHelper( controllerContext.HttpContext, new RouteData(), descriptor, "/Account/SignedOut", "https://localhost/Account/SignedOut"), ControllerContext = new ControllerContext() { HttpContext = controllerContext.HttpContext } }; controller.Request.Scheme = "https"; // Act var result = await controller.SignOut("Custom"); // Assert var signOut = Assert.IsAssignableFrom <SignOutResult>(result); Assert.Equal(new[] { "Cookie", "OpenID" }, signOut.AuthenticationSchemes); }
public void CreateBoundProperties_IgnoresPropertiesWithoutBindingInfo() { // Arrange var actionDescriptor = new PageActionDescriptor(); var handlerTypeInfo = typeof(HandlerWithIgnoredProperties).GetTypeInfo(); var propertyModel1 = new PagePropertyModel( handlerTypeInfo.GetProperty(nameof(HandlerWithIgnoredProperties.Property)), new object[0]) { PropertyName = nameof(HandlerWithIgnoredProperties.Property), BindingInfo = new BindingInfo(), }; var propertyModel2 = new PagePropertyModel( handlerTypeInfo.GetProperty(nameof(HandlerWithIgnoredProperties.IgnoreMe)), new object[0]) { PropertyName = nameof(HandlerWithIgnoredProperties.IgnoreMe), }; var pageApplicationModel = new PageApplicationModel(actionDescriptor, handlerTypeInfo, new object[0]) { HandlerProperties = { propertyModel1, propertyModel2, } }; // Act var propertyDescriptors = CompiledPageActionDescriptorBuilder.CreateBoundProperties(pageApplicationModel); // Assert Assert.Collection( propertyDescriptors, p => { Assert.Same(propertyModel1.PropertyName, p.Name); Assert.Same(typeof(int), p.ParameterType); Assert.Same(propertyModel1.PropertyInfo, p.Property); Assert.Same(propertyModel1.BindingInfo, p.BindingInfo); }); }
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); }); }
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); }, property => { var name = nameof(TestPageModel.TestService); Assert.Equal(modelType.GetProperty(name), property.PropertyInfo); Assert.Equal(name, property.PropertyName); Assert.NotNull(property.BindingInfo); Assert.Equal(BindingSource.Services, property.BindingInfo.BindingSource); }); }
public void CreateDescriptor_ThrowsIfModelIsNotCompatibleWithDeclaredModel() { // Arrange var actionDescriptor = new PageActionDescriptor { ActionConstraints = new List <IActionConstraintMetadata>(), AttributeRouteInfo = new AttributeRouteInfo(), FilterDescriptors = new List <FilterDescriptor>(), RelativePath = "/Foo", RouteValues = new Dictionary <string, string>(), ViewEnginePath = "/Pages/Foo", }; var handlerTypeInfo = typeof(TestModel).GetTypeInfo(); var pageApplicationModel = new PageApplicationModel(actionDescriptor, typeof(TestModel).GetTypeInfo(), handlerTypeInfo, new object[0]) { PageType = typeof(TestPage).GetTypeInfo(), ModelType = typeof(string).GetTypeInfo(), Filters = { Mock.Of <IFilterMetadata>(), Mock.Of <IFilterMetadata>(), }, HandlerMethods = { new PageHandlerModel(handlerTypeInfo.GetMethod(nameof(TestModel.OnGet)), new object[0]), }, HandlerProperties = { new PagePropertyModel(handlerTypeInfo.GetProperty(nameof(TestModel.Property)), new object[0]) { BindingInfo = new BindingInfo(), }, } }; var globalFilters = new FilterCollection(); // Act & Assert var actual = Assert.Throws <InvalidOperationException>(() => CompiledPageActionDescriptorBuilder.Build(pageApplicationModel, globalFilters)); }
public void Load_InvokesApplicationModelConventions() { // Arrange var descriptor = new PageActionDescriptor(); var compilerProvider = GetCompilerProvider(); var model = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), new object[0]); var provider = new Mock <IPageApplicationModelProvider>(); provider.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { c.PageApplicationModel = model; }); var providers = new[] { provider.Object }; var razorPagesOptions = new TestOptionsManager <RazorPagesOptions>(); var mvcOptions = new TestOptionsManager <MvcOptions>(); var convention = new Mock <IPageApplicationModelConvention>(); convention.Setup(c => c.Apply(It.IsAny <PageApplicationModel>())) .Callback((PageApplicationModel m) => { Assert.Same(model, m); }); razorPagesOptions.Value.Conventions.Add(convention.Object); var loader = new DefaultPageLoader( providers, compilerProvider, razorPagesOptions, mvcOptions); // Act var result = loader.Load(new PageActionDescriptor()); // Assert convention.Verify(); }
public void OnProvidersExecuting_AddsFiltersToModel() { // Arrange var actionDescriptor = new PageActionDescriptor(); var applicationModel = new PageApplicationModel( actionDescriptor, typeof(object).GetTypeInfo(), new object[0]); var applicationModelProvider = new AutoValidateAntiforgeryPageApplicationModelProvider(); var context = new PageApplicationModelProviderContext(new PageActionDescriptor(), typeof(object).GetTypeInfo()) { PageApplicationModel = applicationModel, }; // Act applicationModelProvider.OnProvidersExecuting(context); // Assert Assert.Collection( applicationModel.Filters, filter => Assert.IsType <AutoValidateAntiforgeryTokenAttribute>(filter)); }
public void OnProvidersExecuting_AddsFiltersToModel() { // Arrange var actionDescriptor = new PageActionDescriptor(); var applicationModel = new PageApplicationModel( actionDescriptor, typeof(object).GetTypeInfo(), new object[0]); var applicationModelProvider = new TempDataFilterPageApplicationModelProvider(); var context = new PageApplicationModelProviderContext(new PageActionDescriptor(), typeof(object).GetTypeInfo()) { PageApplicationModel = applicationModel, }; // Act applicationModelProvider.OnProvidersExecuting(context); // Assert Assert.Collection( applicationModel.Filters, filter => Assert.IsType <PageSaveTempDataPropertyFilterFactory>(filter)); }
private static CompiledPageActionDescriptor CreateCompiledPageActionDescriptor( PageActionDescriptor descriptor, Type pageType = null) { pageType = pageType ?? typeof(object); var pageTypeInfo = pageType.GetTypeInfo(); TypeInfo modelTypeInfo = null; if (pageType != null) { modelTypeInfo = pageTypeInfo.GetProperty("Model")?.PropertyType.GetTypeInfo(); } return(new CompiledPageActionDescriptor(descriptor) { HandlerTypeInfo = modelTypeInfo ?? pageTypeInfo, ModelTypeInfo = modelTypeInfo ?? pageTypeInfo, PageTypeInfo = pageTypeInfo, FilterDescriptors = Array.Empty <FilterDescriptor>(), }); }
private async Task <CompiledPageActionDescriptor> LoadAsyncCore(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata) { var viewDescriptor = await Compiler.CompileAsync(actionDescriptor.RelativePath); var compiled = _compiledPageActionDescriptorFactory.CreateCompiledDescriptor(actionDescriptor, viewDescriptor); var endpoints = new List <Endpoint>(); _endpointFactory.AddEndpoints( endpoints, routeNames: new HashSet <string>(StringComparer.OrdinalIgnoreCase), action: compiled, routes: Array.Empty <ConventionalRouteEntry>(), groupConventions: Array.Empty <Action <EndpointBuilder> >(), conventions: new Action <EndpointBuilder>[] { b => { // Copy Endpoint metadata for PageActionActionDescriptor to the compiled one. // This is particularly important for the runtime compiled scenario where endpoint metadata is added // to the PageActionDescriptor, which needs to be accounted for when constructing the // CompiledPageActionDescriptor as part of the one of the many matcher policies. // Metadata from PageActionDescriptor is less significant than the one discovered from the compiled type. // Consequently, we'll insert it at the beginning. for (var i = endpointMetadata.Count - 1; i >= 0; i--) { b.Metadata.Insert(0, endpointMetadata[i]); } }, }, createInertEndpoints: false); // In some test scenarios there's no route so the endpoint isn't created. This is fine because // it won't happen for real. compiled.Endpoint = endpoints.SingleOrDefault(); return(compiled); }
public void OnProvidersExecuting_DoesNotAddAutoValidateAntiforgeryTokenAttribute_IfAntiforgeryPolicyExists() { // Arrange var expected = Mock.Of <IAntiforgeryPolicy>(); var descriptor = new PageActionDescriptor(); var provider = new AutoValidateAntiforgeryPageApplicationModelProvider(); var context = new PageApplicationModelProviderContext(descriptor, typeof(object).GetTypeInfo()) { PageApplicationModel = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()) { Filters = { expected }, }, }; // Act provider.OnProvidersExecuting(context); // Assert Assert.Collection( context.PageApplicationModel.Filters, actual => Assert.Same(expected, actual)); }
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); }); }
public CompiledPageActionDescriptor CreateCompiledDescriptor( PageActionDescriptor actionDescriptor, CompiledViewDescriptor viewDescriptor) { var context = new PageApplicationModelProviderContext(actionDescriptor, viewDescriptor.Type !.GetTypeInfo()); for (var i = 0; i < _applicationModelProviders.Length; i++) { _applicationModelProviders[i].OnProvidersExecuting(context); } for (var i = _applicationModelProviders.Length - 1; i >= 0; i--) { _applicationModelProviders[i].OnProvidersExecuted(context); } ApplyConventions(_conventions, context.PageApplicationModel); var compiled = CompiledPageActionDescriptorBuilder.Build(context.PageApplicationModel, _globalFilters); actionDescriptor.CompiledPageDescriptor = compiled; return(compiled); }
public void ApplyConventions_InvokesApplicationModelConventions() { // Arrange var descriptor = new PageActionDescriptor(); var model = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()); var convention = new Mock <IPageApplicationModelConvention>(); convention.Setup(c => c.Apply(It.IsAny <PageApplicationModel>())) .Callback((PageApplicationModel m) => { Assert.Same(model, m); }) .Verifiable(); var conventionCollection = new PageConventionCollection() { convention.Object, }; // Act RuntimeRazorPageLoader.ApplyConventions(conventionCollection, model); // Assert convention.Verify(); }
public override Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata) { if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } if (actionDescriptor is CompiledPageActionDescriptor compiledPageActionDescriptor) { // It's possible for some code paths of PageLoaderMatcherPolicy to invoke LoadAsync with an instance // of CompiledPageActionDescriptor. In that case, we'll return the instance as-is. compiledPageActionDescriptor.CompiledPageActionDescriptorTask ??= Task.FromResult(compiledPageActionDescriptor); return(compiledPageActionDescriptor.CompiledPageActionDescriptorTask); } var task = actionDescriptor.CompiledPageActionDescriptorTask; if (task != null) { return(task); } return(actionDescriptor.CompiledPageActionDescriptorTask = LoadAsyncCore(actionDescriptor, endpointMetadata)); }
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); }); }
protected override ActionDescriptor CreateActionDescriptor( object values, string pattern = null, IList <object> metadata = null) { var action = new PageActionDescriptor(); foreach (var kvp in new RouteValueDictionary(values)) { action.RouteValues[kvp.Key] = kvp.Value?.ToString(); } if (!string.IsNullOrEmpty(pattern)) { action.AttributeRouteInfo = new AttributeRouteInfo { Name = "test", Template = pattern, }; } action.EndpointMetadata = metadata; return(action); }
public Type Load(PageActionDescriptor actionDescriptor) { var source = CreateSourceDocument(actionDescriptor); return(Load(source, actionDescriptor.RelativePath)); }