public CompiledPageActionDescriptor(PageActionDescriptor other) { ActionConstraints = other.ActionConstraints; AttributeRouteInfo = other.AttributeRouteInfo; BoundProperties = other.BoundProperties; DisplayName = other.DisplayName; FilterDescriptors = other.FilterDescriptors; Parameters = other.Parameters; Properties = other.Properties; RelativePath = other.RelativePath; RouteValues = other.RouteValues; ViewEnginePath = other.ViewEnginePath; }
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 = CompiledPageActionDescriptorBuilder.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 <ConventionalRouteEntry>(), 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 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 fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment); var invokerProvider = CreateInvokerProvider( loader.Object, CreateActionDescriptorCollection(descriptor), pageProvider: null, modelProvider: null, razorPageFactoryProvider: pageFactory.Object, fileSystem: fileSystem); var compiledDescriptor = CreateCompiledPageActionDescriptor(descriptor); // Act var factories = invokerProvider.GetViewStartFactories(compiledDescriptor).ToList(); // Assert Assert.Equal(2, factories.Count); }
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); }
private void AddActionDescriptors(IList <ActionDescriptor> actions, PageRouteModel model) { for (var i = 0; i < _conventions.Length; i++) { _conventions[i].Apply(model); } foreach (var selector in model.Selectors) { var descriptor = new PageActionDescriptor { ActionConstraints = selector.ActionConstraints.ToList(), AreaName = model.AreaName, AttributeRouteInfo = new AttributeRouteInfo { Name = selector.AttributeRouteModel.Name, Order = selector.AttributeRouteModel.Order ?? 0, Template = TransformPageRoute(model, selector), SuppressLinkGeneration = selector.AttributeRouteModel.SuppressLinkGeneration, SuppressPathMatching = selector.AttributeRouteModel.SuppressPathMatching, }, DisplayName = $"Page: {model.ViewEnginePath}", EndpointMetadata = selector.EndpointMetadata.ToList(), FilterDescriptors = Array.Empty <FilterDescriptor>(), Properties = new Dictionary <object, object>(model.Properties), RelativePath = model.RelativePath, ViewEnginePath = model.ViewEnginePath, }; foreach (var kvp in model.RouteValues) { if (!descriptor.RouteValues.ContainsKey(kvp.Key)) { descriptor.RouteValues.Add(kvp.Key, kvp.Value); } } if (!descriptor.RouteValues.ContainsKey("page")) { descriptor.RouteValues.Add("page", model.ViewEnginePath); } // Mark all pages as a "dynamic endpoint" - this is how we deal with the compilation of pages // in endpoint routing. descriptor.EndpointMetadata.Add(new DynamicEndpointMetadata()); actions.Add(descriptor); } }
internal Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata) { if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } var task = actionDescriptor.CompiledPageActionDescriptorTask; if (task != null) { return(task); } return(actionDescriptor.CompiledPageActionDescriptorTask = LoadAsyncCore(actionDescriptor, endpointMetadata)); }
public override Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor) { if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } var cache = CurrentCache; if (cache.TryGetValue(actionDescriptor, out var compiledDescriptorTask)) { return(compiledDescriptorTask); } return(cache.GetOrAdd(actionDescriptor, LoadAsyncCore(actionDescriptor))); }
internal Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata) { if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } var cache = CurrentCache; if (cache.TryGetValue(actionDescriptor, out var compiledDescriptorTask)) { return(compiledDescriptorTask); } return(cache.GetOrAdd(actionDescriptor, LoadAsyncCore(actionDescriptor, endpointMetadata))); }
private void AddActionDescriptors(IList <ActionDescriptor> actions, PageRouteModel model) { for (var i = 0; i < _conventions.Length; i++) { _conventions[i].Apply(model); } foreach (var selector in model.Selectors) { var descriptor = new PageActionDescriptor { AttributeRouteInfo = new AttributeRouteInfo { Name = selector.AttributeRouteModel.Name, Order = selector.AttributeRouteModel.Order ?? 0, Template = selector.AttributeRouteModel.Template, SuppressLinkGeneration = selector.AttributeRouteModel.SuppressLinkGeneration, SuppressPathMatching = selector.AttributeRouteModel.SuppressPathMatching, }, DisplayName = $"Page: {model.ViewEnginePath}", FilterDescriptors = Array.Empty <FilterDescriptor>(), Properties = new Dictionary <object, object>(model.Properties), RelativePath = model.RelativePath, ViewEnginePath = model.ViewEnginePath, AreaName = model.AreaName, }; foreach (var kvp in model.RouteValues) { if (!descriptor.RouteValues.ContainsKey(kvp.Key)) { descriptor.RouteValues.Add(kvp.Key, kvp.Value); } } if (!descriptor.RouteValues.ContainsKey("page")) { descriptor.RouteValues.Add("page", model.ViewEnginePath); } actions.Add(descriptor); } }
public CompiledPageActionDescriptor Load(PageActionDescriptor actionDescriptor) { if (actionDescriptor == null) { throw new ArgumentNullException(nameof(actionDescriptor)); } var compileTask = Compiler.CompileAsync(actionDescriptor.RelativePath); var viewDescriptor = compileTask.GetAwaiter().GetResult(); 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); // 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, compiled, Array.Empty <ConventionalRouteEntry>(), Array.Empty <Action <EndpointBuilder> >()); // 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); }
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>(), 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); }
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 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_InvokesPageLoader_WithoutEndpointRouting() { // Arrange var descriptor = new PageActionDescriptor { RelativePath = "/Path1", FilterDescriptors = new FilterDescriptor[0], }; var loader = new Mock <PageLoader>(); loader.Setup(l => l.LoadAsync(descriptor)) .ReturnsAsync(CreateCompiledPageActionDescriptor(descriptor)); var invokerProvider = CreateInvokerProvider( loader.Object, CreateActionDescriptorCollection(descriptor), mvcOptions: new MvcOptions { EnableEndpointRouting = false }); var context = new ActionInvokerProviderContext(new ActionContext { ActionDescriptor = descriptor, HttpContext = new DefaultHttpContext(), RouteData = new RouteData(), }); // Act invokerProvider.OnProvidersExecuting(context); // Assert Assert.NotNull(context.Result); Assert.IsType <PageActionInvoker>(context.Result); loader.Verify(l => l.LoadAsync(It.IsAny <PageActionDescriptor>()), Times.Once()); }
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 OnProvidersExecuting_WithModel_PopulatesCacheEntry() { // Arrange var descriptor = new PageActionDescriptor { RelativePath = "/Path1", FilterDescriptors = new FilterDescriptor[0] }; Func <PageContext, ViewContext, object> factory = (a, b) => null; Action <PageContext, ViewContext, object> releaser = (a, b, c) => { }; Func <PageContext, object> modelFactory = _ => null; Action <PageContext, object> modelDisposer = (_, __) => { }; var loader = new Mock <IPageLoader>(); loader .Setup(l => l.Load(It.IsAny <PageActionDescriptor>())) .Returns(CreateCompiledPageActionDescriptor( descriptor, pageType: typeof(PageWithModel), modelType: typeof(DerivedTestPageModel))); var pageFactoryProvider = new Mock <IPageFactoryProvider>(); pageFactoryProvider .Setup(f => f.CreatePageFactory(It.IsAny <CompiledPageActionDescriptor>())) .Returns(factory); pageFactoryProvider .Setup(f => f.CreatePageDisposer(It.IsAny <CompiledPageActionDescriptor>())) .Returns(releaser); var modelFactoryProvider = new Mock <IPageModelFactoryProvider>(); modelFactoryProvider .Setup(f => f.CreateModelFactory(It.IsAny <CompiledPageActionDescriptor>())) .Returns(modelFactory); modelFactoryProvider .Setup(f => f.CreateModelDisposer(It.IsAny <CompiledPageActionDescriptor>())) .Returns(modelDisposer); var invokerProvider = CreateInvokerProvider( loader.Object, CreateActionDescriptorCollection(descriptor), pageFactoryProvider.Object, modelFactoryProvider.Object); var context = new ActionInvokerProviderContext(new ActionContext() { ActionDescriptor = descriptor, HttpContext = new DefaultHttpContext(), RouteData = new RouteData(), }); // Act invokerProvider.OnProvidersExecuting(context); // Assert Assert.NotNull(context.Result); var actionInvoker = Assert.IsType <PageActionInvoker>(context.Result); var entry = actionInvoker.CacheEntry; var compiledPageActionDescriptor = Assert.IsType <CompiledPageActionDescriptor>(entry.ActionDescriptor); Assert.Equal(descriptor.RelativePath, compiledPageActionDescriptor.RelativePath); Assert.Same(factory, entry.PageFactory); Assert.Same(releaser, entry.ReleasePage); Assert.Same(modelFactory, entry.ModelFactory); Assert.Same(modelDisposer, entry.ReleaseModel); Assert.NotNull(entry.ViewDataFactory); var pageContext = actionInvoker.PageContext; Assert.Same(compiledPageActionDescriptor, pageContext.ActionDescriptor); Assert.Same(context.ActionContext.HttpContext, pageContext.HttpContext); Assert.Same(context.ActionContext.ModelState, pageContext.ModelState); Assert.Same(context.ActionContext.RouteData, pageContext.RouteData); Assert.Empty(pageContext.ValueProviderFactories); Assert.NotNull(Assert.IsType <ViewDataDictionary <TestPageModel> >(pageContext.ViewData)); Assert.Empty(pageContext.ViewStartFactories); }
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 <IPageLoader>(); loader .Setup(l => l.Load(It.IsAny <PageActionDescriptor>())) .Returns(compiledPageDescriptor); var fileProvider = new TestFileProvider(); fileProvider.AddFile("/_ViewStart.cshtml", "page content"); fileProvider.AddFile("/Pages/_ViewStart.cshtml", "page content"); fileProvider.AddFile("/Pages/Level1/_ViewStart.cshtml", "page content"); fileProvider.AddFile("/Pages/Level1/Level2/_ViewStart.cshtml", "page content"); fileProvider.AddFile("/Pages/Level1/Level3/_ViewStart.cshtml", "page content"); var fileSystem = new TestRazorProjectFileSystem(fileProvider, _hostingEnvironment); 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, CreateActionDescriptorCollection(descriptor), razorPageFactoryProvider: razorPageFactoryProvider, fileSystem: fileSystem); // Act var factories = invokerProvider.GetViewStartFactories(compiledPageDescriptor); // Assert mock.Verify(); }
public void Load_InvokesApplicationModelProviders_WithTheRightOrder() { // Arrange var descriptor = new PageActionDescriptor(); var compilerProvider = GetCompilerProvider(); var razorPagesOptions = Options.Create(new RazorPagesOptions()); var mvcOptions = Options.Create(new MvcOptions()); var provider1 = new Mock <IPageApplicationModelProvider>(); provider1.SetupGet(p => p.Order).Returns(10); var provider2 = new Mock <IPageApplicationModelProvider>(); provider2.SetupGet(p => p.Order).Returns(-5); var sequence = 0; provider1.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(1, sequence++); c.PageApplicationModel = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()); }) .Verifiable(); provider2.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(0, sequence++); }) .Verifiable(); provider1.Setup(p => p.OnProvidersExecuted(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(2, sequence++); }) .Verifiable(); provider2.Setup(p => p.OnProvidersExecuted(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(3, sequence++); }) .Verifiable(); var providers = new[] { provider1.Object, provider2.Object }; var loader = new DefaultPageLoader( providers, compilerProvider, razorPagesOptions, mvcOptions); // Act var result = loader.Load(new PageActionDescriptor()); // Assert provider1.Verify(); provider2.Verify(); }
/// <summary> /// Produces a <see cref="CompiledPageActionDescriptor"/> given a <see cref="PageActionDescriptor"/>. /// </summary> /// <param name="actionDescriptor">The <see cref="PageActionDescriptor"/>.</param> /// <param name="endpointMetadata">The <see cref="EndpointMetadataCollection"/>.</param> /// <returns>A <see cref="Task"/> that on completion returns a <see cref="CompiledPageActionDescriptor"/>.</returns> public virtual Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor, EndpointMetadataCollection endpointMetadata) => throw new NotSupportedException();
CompiledPageActionDescriptor IPageLoader.Load(PageActionDescriptor actionDescriptor) => LoadAsync(actionDescriptor, EndpointMetadataCollection.Empty).GetAwaiter().GetResult();
public async Task LoadAsync_InvokesApplicationModelProviders_WithTheRightOrder() { // Arrange var descriptor = new PageActionDescriptor(); var compilerProvider = GetCompilerProvider(); var mvcOptions = Options.Create(new MvcOptions()); var endpointFactory = new ActionEndpointFactory(Mock.Of <RoutePatternTransformer>(), Enumerable.Empty <IRequestDelegateFactory>()); var provider1 = new Mock <IPageApplicationModelProvider>(); provider1.SetupGet(p => p.Order).Returns(10); var provider2 = new Mock <IPageApplicationModelProvider>(); provider2.SetupGet(p => p.Order).Returns(-5); var sequence = 0; provider1.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(1, sequence++); c.PageApplicationModel = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()); }) .Verifiable(); provider2.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(0, sequence++); }) .Verifiable(); provider1.Setup(p => p.OnProvidersExecuted(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(2, sequence++); }) .Verifiable(); provider2.Setup(p => p.OnProvidersExecuted(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(3, sequence++); }) .Verifiable(); var providers = new[] { provider1.Object, provider2.Object }; var loader = new DefaultPageLoader( providers, compilerProvider, endpointFactory, RazorPagesOptions, mvcOptions); // Act var result = await loader.LoadAsync(new PageActionDescriptor()); // Assert provider1.Verify(); provider2.Verify(); }
public override Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor) => LoadAsync(actionDescriptor, EndpointMetadataCollection.Empty);
public async Task LoadAsync_InvokesApplicationModelProviders() { // Arrange var descriptor = new PageActionDescriptor(); var compilerProvider = GetCompilerProvider(); var razorPagesOptions = Options.Create(new RazorPagesOptions()); var mvcOptions = Options.Create(new MvcOptions()); var endpointFactory = new ActionEndpointFactory(Mock.Of <RoutePatternTransformer>()); var provider1 = new Mock <IPageApplicationModelProvider>(); var provider2 = new Mock <IPageApplicationModelProvider>(); var sequence = 0; var pageApplicationModel1 = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()); var pageApplicationModel2 = new PageApplicationModel(descriptor, typeof(object).GetTypeInfo(), Array.Empty <object>()); provider1.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(0, sequence++); Assert.Null(c.PageApplicationModel); c.PageApplicationModel = pageApplicationModel1; }) .Verifiable(); provider2.Setup(p => p.OnProvidersExecuting(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(1, sequence++); Assert.Same(pageApplicationModel1, c.PageApplicationModel); c.PageApplicationModel = pageApplicationModel2; }) .Verifiable(); provider1.Setup(p => p.OnProvidersExecuted(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(3, sequence++); Assert.Same(pageApplicationModel2, c.PageApplicationModel); }) .Verifiable(); provider2.Setup(p => p.OnProvidersExecuted(It.IsAny <PageApplicationModelProviderContext>())) .Callback((PageApplicationModelProviderContext c) => { Assert.Equal(2, sequence++); Assert.Same(pageApplicationModel2, c.PageApplicationModel); }) .Verifiable(); var providers = new[] { provider1.Object, provider2.Object }; var loader = new DefaultPageLoader( ActionDescriptorCollectionProvider, providers, compilerProvider, endpointFactory, razorPagesOptions, mvcOptions); // Act var result = await loader.LoadAsync(new PageActionDescriptor()); // Assert provider1.Verify(); provider2.Verify(); }
public async Task LoadAsync_UpdatesResults() { // 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 razorPagesOptions = Options.Create(new RazorPagesOptions()); var mvcOptions = Options.Create(new MvcOptions()); var endpointFactory = new ActionEndpointFactory(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 descriptorCollection1 = new ActionDescriptorCollection(new[] { descriptor }, version: 1); var descriptorCollection2 = new ActionDescriptorCollection(new[] { descriptor }, version: 2); var actionDescriptorCollectionProvider = new Mock <IActionDescriptorCollectionProvider>(); actionDescriptorCollectionProvider .SetupSequence(p => p.ActionDescriptors) .Returns(descriptorCollection1) .Returns(descriptorCollection2); var loader = new DefaultPageLoader( actionDescriptorCollectionProvider.Object, providers, compilerProvider, endpointFactory, razorPagesOptions, mvcOptions); // Act var result1 = await loader.LoadAsync(descriptor); var result2 = await loader.LoadAsync(descriptor); // Assert Assert.NotSame(result1, result2); }
/// <summary> /// Produces a <see cref="CompiledPageActionDescriptor"/> given a <see cref="PageActionDescriptor"/>. /// </summary> /// <param name="actionDescriptor">The <see cref="PageActionDescriptor"/>.</param> /// <returns>A <see cref="Task"/> that on completion returns a <see cref="CompiledPageActionDescriptor"/>.</returns> public abstract Task <CompiledPageActionDescriptor> LoadAsync(PageActionDescriptor actionDescriptor);
CompiledPageActionDescriptor IPageLoader.Load(PageActionDescriptor actionDescriptor) => LoadAsync(actionDescriptor).GetAwaiter().GetResult();