diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageActionInvoker.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageActionInvoker.cs index 66c01029da..53fc6b1fe0 100644 --- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageActionInvoker.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageActionInvoker.cs @@ -141,23 +141,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal private Task BindArgumentsAsync() { - // This is a temporary workaround. - PageSaveTempDataPropertyFilter propertyFilter = null; - for (var i = 0; i < _filters.Length; i++) - { - propertyFilter = _filters[i] as PageSaveTempDataPropertyFilter; - if (propertyFilter != null) - { - break; - } - } - - if (propertyFilter != null) - { - propertyFilter.Subject = _instance; - propertyFilter.ApplyTempDataChanges(_pageContext.HttpContext); - } - // Perf: Avoid allocating async state machines where possible. We only need the state // machine if you need to bind properties or arguments. if (_actionDescriptor.BoundProperties.Count == 0 && (_handler == null || _handler.Parameters.Count == 0)) diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageSaveTempDataPropertyFilter.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageSaveTempDataPropertyFilter.cs new file mode 100644 index 0000000000..a7b45146df --- /dev/null +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageSaveTempDataPropertyFilter.cs @@ -0,0 +1,52 @@ +// 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 Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; + +namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal +{ + public class PageSaveTempDataPropertyFilter : SaveTempDataPropertyFilterBase, IPageFilter + { + public PageSaveTempDataPropertyFilter(ITempDataDictionaryFactory factory) + : base(factory) + { + } + + public PageSaveTempDataPropertyFilterFactory FilterFactory { get; set; } + + public void OnPageHandlerSelected(PageHandlerSelectedContext context) + { + } + + public void OnPageHandlerExecuting(PageHandlerExecutingContext context) + { + if (context.HandlerInstance == null) + { + throw new InvalidOperationException(Resources.FormatPropertyOfTypeCannotBeNull( + nameof(PageHandlerExecutingContext.HandlerInstance), + typeof(PageHandlerExecutingContext).Name)); + } + + if (FilterFactory == null) + { + throw new InvalidOperationException(Resources.FormatPropertyOfTypeCannotBeNull( + nameof(FilterFactory), + typeof(PageSaveTempDataPropertyFilter).Name)); + } + + var tempData = _factory.GetTempData(context.HttpContext); + + Subject = context.HandlerInstance; + Properties = FilterFactory.GetTempDataProperties(Subject.GetType()); + + SetPropertyVaules(tempData, Subject); + } + + public void OnPageHandlerExecuted(PageHandlerExecutedContext context) + { + } + } +} diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/PageSaveTempDataPropertyFilterFactory.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageSaveTempDataPropertyFilterFactory.cs similarity index 79% rename from src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/PageSaveTempDataPropertyFilterFactory.cs rename to src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageSaveTempDataPropertyFilterFactory.cs index 50f1e053b6..66618a722a 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/PageSaveTempDataPropertyFilterFactory.cs +++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PageSaveTempDataPropertyFilterFactory.cs @@ -4,13 +4,14 @@ using System; using System.Collections.Generic; using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; using Microsoft.Extensions.DependencyInjection; -namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal +namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal { public class PageSaveTempDataPropertyFilterFactory : IFilterFactory { - public IList TempDataProperties { get; set; } + public IList Properties { get; set; } public bool IsReusable => false; @@ -32,12 +33,12 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal // TempDataProperties are stored here as a cache for the filter. But in pages by the time we know the type // of our model we no longer have access to the factory, so we store the factory on the filter so it can // call this method to populate its TempDataProperties. - if (TempDataProperties == null) + if (Properties == null) { - TempDataProperties = SaveTempDataPropertyFilterBase.GetTempDataProperties(modelType); + Properties = SaveTempDataPropertyFilterBase.GetTempDataProperties(modelType); } - return TempDataProperties; + return Properties; } } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/ControllerSaveTempDataPropertyFilter.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/ControllerSaveTempDataPropertyFilter.cs similarity index 100% rename from src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/ControllerSaveTempDataPropertyFilter.cs rename to src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/ControllerSaveTempDataPropertyFilter.cs diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/ControllerSaveTempDataPropertyFilterFactory.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/ControllerSaveTempDataPropertyFilterFactory.cs similarity index 93% rename from src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/ControllerSaveTempDataPropertyFilterFactory.cs rename to src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/ControllerSaveTempDataPropertyFilterFactory.cs index 110c01eb03..98e1272b21 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/ControllerSaveTempDataPropertyFilterFactory.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/ControllerSaveTempDataPropertyFilterFactory.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal } var service = serviceProvider.GetRequiredService(); - service.TempDataProperties = TempDataProperties; + service.Properties = TempDataProperties; return service; } } diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/PageSaveTempDataPropertyFilter.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/PageSaveTempDataPropertyFilter.cs deleted file mode 100644 index 636cee7ceb..0000000000 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/PageSaveTempDataPropertyFilter.cs +++ /dev/null @@ -1,65 +0,0 @@ -// 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 Microsoft.AspNetCore.Http; - -namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal -{ - public class PageSaveTempDataPropertyFilter : SaveTempDataPropertyFilterBase - { - public PageSaveTempDataPropertyFilter(ITempDataDictionaryFactory factory) - : base(factory) - { - } - - public PageSaveTempDataPropertyFilterFactory FilterFactory { get; set; } - - public override object Subject { - get => base.Subject; - set - { - base.Subject = value; - SetTempDataProperties(value.GetType()); - } - } - - private void SetTempDataProperties(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - if (FilterFactory == null) - { - throw new InvalidOperationException( - Resources.FormatPropertyOfTypeCannotBeNull( - nameof(FilterFactory), - typeof(PageSaveTempDataPropertyFilter).Name)); - } - - TempDataProperties = FilterFactory.GetTempDataProperties(type); - } - - /// - /// Applies values from TempData from to the - /// . - /// - /// The used to find TempData. - public void ApplyTempDataChanges(HttpContext httpContext) - { - if (Subject == null) - { - throw new InvalidOperationException( - Resources.FormatPropertyOfTypeCannotBeNull( - nameof(Subject), - typeof(PageSaveTempDataPropertyFilter).Name)); - } - - var tempData = _factory.GetTempData(httpContext); - - SetPropertyVaules(tempData, Subject); - } - } -} diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/SaveTempDataPropertyFilterBase.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilterBase.cs similarity index 88% rename from src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/SaveTempDataPropertyFilterBase.cs rename to src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilterBase.cs index 03f4e633b7..6f194ce986 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/SaveTempDataPropertyFilterBase.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilterBase.cs @@ -17,12 +17,12 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal /// /// Describes the temp data properties which exist on /// - public IList TempDataProperties { get; set; } + public IList Properties { get; set; } /// /// The which has the temp data properties. /// - public virtual object Subject { get; set; } + public object Subject { get; set; } /// /// Tracks the values which originally existed in temp data. @@ -40,17 +40,17 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal /// The to be updated. public void OnTempDataSaving(ITempDataDictionary tempData) { - if (Subject != null && OriginalValues != null) + if (Subject != null && Properties != null) { - foreach (var kvp in OriginalValues) + for (var i = 0; i < Properties.Count; i++) { - var property = kvp.Key; - var originalValue = kvp.Value; + var property = Properties[i]; + OriginalValues.TryGetValue(property.PropertyInfo, out var originalValue); var newValue = property.GetValue(Subject); if (newValue != null && !newValue.Equals(originalValue)) { - tempData[Prefix + property.Name] = newValue; + tempData[property.TempDataKey] = newValue; } } } @@ -74,6 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal } results.Add(new TempDataProperty( + Prefix + propertyHelper.Name, propertyHelper.Property, propertyHelper.GetValue, propertyHelper.SetValue)); @@ -109,14 +110,14 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal /// The which will have it's properties set. protected void SetPropertyVaules(ITempDataDictionary tempData, object subject) { - if (TempDataProperties == null) + if (Properties == null) { return; } - for (var i = 0; i < TempDataProperties.Count; i++) + for (var i = 0; i < Properties.Count; i++) { - var property = TempDataProperties[i]; + var property = Properties[i]; var value = tempData[Prefix + property.PropertyInfo.Name]; OriginalValues[property.PropertyInfo] = value; diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/TempDataProperty.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/TempDataProperty.cs similarity index 78% rename from src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/TempDataProperty.cs rename to src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/TempDataProperty.cs index 8a0349048e..85a9027b7d 100644 --- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/SaveTempDataPropertyFilter/TempDataProperty.cs +++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Internal/TempDataProperty.cs @@ -12,13 +12,16 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal private readonly Action _setter; - public TempDataProperty(PropertyInfo propertyInfo, Func getter, Action setter) + public TempDataProperty(string tempDataKey, PropertyInfo propertyInfo, Func getter, Action setter) { + TempDataKey = tempDataKey; PropertyInfo = propertyInfo; _getter = getter; _setter = setter; } + public string TempDataKey { get; } + public PropertyInfo PropertyInfo { get; } public object GetValue(object obj) diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/PageSaveTempDataPropertyFilterFactoryTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageSaveTempDataPropertyFilterFactoryTest.cs similarity index 92% rename from test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/PageSaveTempDataPropertyFilterFactoryTest.cs rename to test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageSaveTempDataPropertyFilterFactoryTest.cs index f56320a41d..6d116a586d 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/PageSaveTempDataPropertyFilterFactoryTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageSaveTempDataPropertyFilterFactoryTest.cs @@ -2,10 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Moq; using Xunit; -namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal +namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal { public class PageSaveTempDataPropertyFilterFactoryTest { diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageSaveTempDataPropertyFilterTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageSaveTempDataPropertyFilterTest.cs new file mode 100644 index 0000000000..a0cd75d1a5 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageSaveTempDataPropertyFilterTest.cs @@ -0,0 +1,289 @@ +// 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.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; +using Microsoft.AspNetCore.Routing; +using Moq; +using Xunit; + +namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal +{ + public class PageSaveTempDataPropertyFilterTest + { + [Fact] + public void OnTempDataSaving_PopulatesTempDataWithNewValuesFromPageProperties() + { + // Arrange + var httpContext = new DefaultHttpContext(); + + var tempData = new TempDataDictionary(httpContext, Mock.Of()); + + var page = new TestPage() + { + Test = "TestString", + Test2 = "Test2", + }; + + var filter = CreatePageSaveTempDataPropertyFilter(tempData); + filter.Subject = page; + + var pageType = page.GetType(); + + var testProperty = pageType.GetProperty(nameof(TestPage.Test)); + var test2Property = pageType.GetProperty(nameof(TestPage.Test2)); + + filter.OriginalValues[testProperty] = "SomeValue"; + filter.OriginalValues[test2Property] = "Test2"; + + filter.Properties = new List + { + new TempDataProperty("TempDataProperty-Test", testProperty, testProperty.GetValue, testProperty.SetValue), + new TempDataProperty("TempDataProperty-Test2", test2Property, test2Property.GetValue, test2Property.SetValue) + }; + + // Act + filter.OnTempDataSaving(tempData); + + // Assert + Assert.Equal("TestString", page.Test); + Assert.Equal("TestString", tempData["TempDataProperty-Test"]); + Assert.False(tempData.ContainsKey("TestDataProperty-Test2")); + } + + [Fact] + public void OnPageExecuting_NullFilterFactory_Throws() + { + // Arrange + var httpContext = new DefaultHttpContext(); + var tempData = new TempDataDictionary(httpContext, Mock.Of()); + tempData.Save(); + + var page = new TestPage(); + + var filter = CreatePageSaveTempDataPropertyFilter(tempData, filterFactory: false); + + var context = new PageHandlerExecutingContext( + new PageContext() + { + ActionDescriptor = new CompiledPageActionDescriptor(), + HttpContext = httpContext, + RouteData = new RouteData(), + }, + Array.Empty(), + null, + new Dictionary(), + page); + + // Act & Assert + var ex = Assert.Throws(() => filter.OnPageHandlerExecuting(context)); + Assert.Contains("FilterFactory", ex.Message); + } + + [Fact] + public void OnPageExecuting_ToPageModel_SetsPropertyValue() + { + // Arrange + var httpContext = new DefaultHttpContext(); + + var tempData = new TempDataDictionary(httpContext, Mock.Of()) + { + { "TempDataProperty-Test", "Value" } + }; + tempData.Save(); + + var pageModel = new TestPageModel(); + + var filter = CreatePageSaveTempDataPropertyFilter(tempData); + filter.Subject = pageModel; + + var pageType = typeof(TestPageModel); + var testProperty = pageType.GetProperty(nameof(TestPageModel.Test)); + var test2Property = pageType.GetProperty(nameof(TestPageModel.Test2)); + + var context = new PageHandlerExecutingContext( + new PageContext() + { + ActionDescriptor = new CompiledPageActionDescriptor(), + HttpContext = httpContext, + RouteData = new RouteData(), + }, + Array.Empty(), + null, + new Dictionary(), + pageModel); + + // Act + filter.OnPageHandlerExecuting(context); + + // Assert + Assert.Equal("Value", pageModel.Test); + Assert.Null(pageModel.Test2); + } + + [Fact] + public void OnPageExecuting_ToPage_SetsPropertyValue() + { + // Arrange + var httpContext = new DefaultHttpContext(); + + var tempData = new TempDataDictionary(httpContext, Mock.Of()) + { + { "TempDataProperty-Test", "Value" } + }; + tempData.Save(); + + var page = new TestPage() + { + ViewContext = CreateViewContext(httpContext, tempData) + }; + + var filter = CreatePageSaveTempDataPropertyFilter(tempData); + filter.Subject = page; + + var pageType = page.GetType(); + var testProperty = pageType.GetProperty(nameof(TestPage.Test)); + var test2Property = pageType.GetProperty(nameof(TestPage.Test2)); + + var context = new PageHandlerExecutingContext( + new PageContext() + { + ActionDescriptor = new CompiledPageActionDescriptor(), + HttpContext = httpContext, + RouteData = new RouteData(), + }, + Array.Empty(), + null, + new Dictionary(), + page); + + // Act + filter.OnPageHandlerExecuting(context); + + // Assert + Assert.Equal("Value", page.Test); + Assert.Null(page.Test2); + } + + [Fact] + public void OnPageExecuting_InitializesAndSavesProperties() + { + // Arrange + var httpContext = new DefaultHttpContext(); + + var tempData = new TempDataDictionary(httpContext, Mock.Of()) + { + { "TempDataProperty-Test", "Value" } + }; + tempData.Save(); + + var pageModel = new TestPageModel(); + + var filter = CreatePageSaveTempDataPropertyFilter(tempData); + filter.Subject = pageModel; + + var factory = filter.FilterFactory; + + var pageType = typeof(TestPageModel); + var testProperty = pageType.GetProperty(nameof(TestPageModel.Test)); + var test2Property = pageType.GetProperty(nameof(TestPageModel.Test2)); + + filter.Properties = new List + { + new TempDataProperty("TempDataProperty-Test", testProperty, testProperty.GetValue, testProperty.SetValue), + new TempDataProperty("TempDataProperty-Test2", test2Property, test2Property.GetValue, test2Property.SetValue) + }; + + var context = new PageHandlerExecutingContext( + new PageContext() + { + ActionDescriptor = new CompiledPageActionDescriptor(), + HttpContext = httpContext, + RouteData = new RouteData(), + }, + Array.Empty(), + null, + new Dictionary(), + pageModel); + + // Act + filter.OnPageHandlerExecuting(context); + + // Assert + Assert.Collection( + filter.Properties.OrderBy(p => p.PropertyInfo.Name), + p => Assert.Equal(testProperty, p.PropertyInfo), + p => Assert.Equal(test2Property, p.PropertyInfo)); + + Assert.Same(filter.Properties, factory.Properties); + } + + private static ViewContext CreateViewContext(HttpContext httpContext, ITempDataDictionary tempData) + { + var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + var metadataProvider = new EmptyModelMetadataProvider(); + var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary()); + var viewContext = new ViewContext( + actionContext, + NullView.Instance, + viewData, + tempData, + TextWriter.Null, + new HtmlHelperOptions()); + + return viewContext; + } + + private PageSaveTempDataPropertyFilter CreatePageSaveTempDataPropertyFilter( + TempDataDictionary tempData, + bool filterFactory = true) + { + var factory = new Mock(); + factory + .Setup(f => f.GetTempData(It.IsAny())) + .Returns(tempData); + + var propertyFilter = new PageSaveTempDataPropertyFilter(factory.Object); + + if (filterFactory) + { + propertyFilter.FilterFactory = Mock.Of(); + } + + return propertyFilter; + } + + public class TestPage : Page + { + [TempData] + public string Test { get; set; } + + [TempData] + public string Test2 { get; set; } + + public override Task ExecuteAsync() + { + throw new NotImplementedException(); + } + } + + public class TestPageModel : PageModel + { + [TempData] + public string Test { get; set; } + + [TempData] + public string Test2 { get; set; } + } + } +} diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/ControllerSaveTempDataPropertyFilterFactoryTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ControllerSaveTempDataPropertyFilterFactoryTest.cs similarity index 82% rename from test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/ControllerSaveTempDataPropertyFilterFactoryTest.cs rename to test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ControllerSaveTempDataPropertyFilterFactoryTest.cs index db8aa9abc3..958ea08dba 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/ControllerSaveTempDataPropertyFilterFactoryTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ControllerSaveTempDataPropertyFilterFactoryTest.cs @@ -19,16 +19,16 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal factory.TempDataProperties = new List() { - new TempDataProperty(propertyInfo, null, null) + new TempDataProperty("TempDataProperty-StringProp", propertyInfo, null, null) }; // Act var filter = factory.CreateInstance(CreateServiceProvider()); // Assert - var controllerFilter = Assert.IsType(filter); - Assert.Collection(controllerFilter.TempDataProperties, - property => Assert.Equal("StringProp", property.PropertyInfo.Name)); + Assert.Collection( + Assert.IsType(filter).Properties, + property => Assert.Equal(propertyInfo, property.PropertyInfo)); } private ServiceProvider CreateServiceProvider() diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/ControllerSaveTempDataPropertyFilterTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ControllerSaveTempDataPropertyFilterTest.cs similarity index 77% rename from test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/ControllerSaveTempDataPropertyFilterTest.cs rename to test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ControllerSaveTempDataPropertyFilterTest.cs index eccd8a6d22..9c6d6a5aac 100644 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/ControllerSaveTempDataPropertyFilterTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/ControllerSaveTempDataPropertyFilterTest.cs @@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal var controller = new TestController(); var controllerType = controller.GetType(); - var testProp = controllerType.GetProperty(nameof(TestController.Test)); - var test2Prop = controllerType.GetProperty(nameof(TestController.Test2)); + var testProperty = controllerType.GetProperty(nameof(TestController.Test)); + var test2Property = controllerType.GetProperty(nameof(TestController.Test2)); - filter.TempDataProperties = new List + filter.Properties = new List { - new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue), - new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue) + new TempDataProperty("TempDataProperty-Test", testProperty, testProperty.GetValue, testProperty.SetValue), + new TempDataProperty("TempDataProperty-Test2", test2Property, test2Property.GetValue, test2Property.SetValue) }; var context = new ActionExecutingContext( @@ -73,13 +73,13 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal var controller = new TestController(); var controllerType = controller.GetType(); - var testProp = controllerType.GetProperty(nameof(TestController.Test)); - var test2Prop = controllerType.GetProperty(nameof(TestController.Test2)); + var testProperty = controllerType.GetProperty(nameof(TestController.Test)); + var test2Property = controllerType.GetProperty(nameof(TestController.Test2)); - filter.TempDataProperties = new List + filter.Properties = new List { - new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue), - new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue) + new TempDataProperty("TempDataProperty-Test", testProperty, testProperty.GetValue, testProperty.SetValue), + new TempDataProperty("TempDataProperty-Test2", test2Property, test2Property.GetValue, test2Property.SetValue) }; var context = new ActionExecutingContext( @@ -107,7 +107,8 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal TempDataDictionary tempData) { var factory = new Mock(); - factory.Setup(f => f.GetTempData(httpContext)) + factory + .Setup(f => f.GetTempData(httpContext)) .Returns(tempData); return new ControllerSaveTempDataPropertyFilter(factory.Object); diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/PageSaveTempDataPropertyFilterTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/PageSaveTempDataPropertyFilterTest.cs deleted file mode 100644 index 8f04bc0984..0000000000 --- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/PageSaveTempDataPropertyFilterTest.cs +++ /dev/null @@ -1,251 +0,0 @@ -// 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.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc.Abstractions; -using Microsoft.AspNetCore.Mvc.ModelBinding; -using Microsoft.AspNetCore.Mvc.RazorPages; -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.AspNetCore.Routing; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.Mvc.ViewFeatures.Internal -{ - public class PageSaveTempDataPropertyFilterTest - { - [Fact] - public void OnTempDataSaving_PopulatesTempDataWithValuesFromPageProperty() - { - // Arrange - var httpContext = new DefaultHttpContext(); - - var tempData = new TempDataDictionary(httpContext, Mock.Of()) - { - { "TempDataProperty-Test", "TestString" } - }; - tempData.Save(); - - var page = new TestPageString() - { - Test = "TestString", - ViewContext = CreateViewContext(httpContext, tempData) - }; - - var provider = CreatePageSaveTempDataPropertyFilter(httpContext, tempData: tempData); - provider.Subject = page; - - var pageType = page.GetType(); - - var testProp = pageType.GetProperty(nameof(TestPageString.Test)); - var test2Prop = pageType.GetProperty(nameof(TestPageString.Test2)); - - provider.TempDataProperties = new List{ - new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue), - new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue) - }; - - // Act - provider.OnTempDataSaving(tempData); - - // Assert - Assert.Equal("TestString", page.Test); - Assert.Equal("TestString", page.TempData["TempDataProperty-Test"]); - } - - [Fact] - public void SetSubject_NullFilterFactory_Throws() - { - // Arrange - var httpContext = new DefaultHttpContext(); - var tempData = new TempDataDictionary(httpContext, Mock.Of()); - tempData.Save(); - - var page = new TestPageString() - { - ViewContext = CreateViewContext(httpContext, tempData) - }; - - var provider = CreatePageSaveTempDataPropertyFilter(httpContext, tempData: tempData, filterFactory: false); - - // Act & Assert - var ex = Assert.Throws(() => provider.Subject = page); - Assert.Contains("FilterFactory", ex.Message); - } - - [Fact] - public void SetSubject_ModifiesFactoryAndFilter() - { - // Arrange - var httpContext = new DefaultHttpContext(); - - var tempData = new TempDataDictionary(httpContext, Mock.Of()); - tempData.Save(); - - var page = new TestPageString() - { - Test = "TestString", - ViewContext = CreateViewContext(httpContext, tempData) - }; - - var provider = CreatePageSaveTempDataPropertyFilter(httpContext, tempData: tempData); - provider.FilterFactory = new PageSaveTempDataPropertyFilterFactory(); - - // Act - provider.Subject = page; - - // Assert - Assert.Collection(provider.TempDataProperties, - property => Assert.Equal("Test", property.PropertyInfo.Name), - property => Assert.Equal("Test2", property.PropertyInfo.Name)); - } - - [Fact] - public void ApplyTempDataChanges_ToPageModel_SetsPropertyValue() - { - // Arrange - var httpContext = new DefaultHttpContext(); - - var tempData = new TempDataDictionary(httpContext, Mock.Of()) - { - { "TempDataProperty-Test", "Value" } - }; - tempData.Save(); - - var page = new TestPageString() - { - ViewContext = CreateViewContext(httpContext, tempData) - }; - - var provider = CreatePageSaveTempDataPropertyFilter(httpContext, tempData: tempData); - provider.Subject = page; - - var pageType = typeof(TestPageString); - var testProp = pageType.GetProperty("Test"); - var test2Prop = pageType.GetProperty("Test2"); - - provider.TempDataProperties = new List { - new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue), - new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue) - }; - - // Act - provider.ApplyTempDataChanges(httpContext); - - // Assert - Assert.Equal("Value", page.Test); - Assert.Null(page.Test2); - } - - [Fact] - public void ApplyTempDataChanges_ToPage_SetsPropertyValue() - { - // Arrange - var httpContext = new DefaultHttpContext(); - - var tempData = new TempDataDictionary(httpContext, Mock.Of()) - { - { "TempDataProperty-Test", "Value" } - }; - tempData.Save(); - - var page = new TestPageString() - { - ViewContext = CreateViewContext(httpContext, tempData) - }; - - var provider = CreatePageSaveTempDataPropertyFilter(httpContext, tempData: tempData); - provider.Subject = page; - - var pageType = page.GetType(); - - var testProp = pageType.GetProperty(nameof(TestPageString.Test)); - var test2Prop = pageType.GetProperty(nameof(TestPageString.Test2)); - - provider.TempDataProperties = new List - { - new TempDataProperty(testProp, testProp.GetValue, testProp.SetValue), - new TempDataProperty(test2Prop, test2Prop.GetValue, test2Prop.SetValue) - }; - - // Act - provider.ApplyTempDataChanges(httpContext); - - // Assert - Assert.Equal("Value", page.Test); - Assert.Null(page.Test2); - } - - private static ViewContext CreateViewContext(HttpContext httpContext, ITempDataDictionary tempData) - { - var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); - var metadataProvider = new EmptyModelMetadataProvider(); - var viewData = new ViewDataDictionary(metadataProvider, new ModelStateDictionary()); - var viewContext = new ViewContext( - actionContext, - NullView.Instance, - viewData, - tempData, - TextWriter.Null, - new HtmlHelperOptions()); - - return viewContext; - } - - private PageSaveTempDataPropertyFilter CreatePageSaveTempDataPropertyFilter( - HttpContext httpContext, - TempDataDictionary tempData, - bool filterFactory = true) - { - var factory = new Mock(); - factory.Setup(f => f.GetTempData(httpContext)) - .Returns(tempData); - - var propertyFilter = new PageSaveTempDataPropertyFilter(factory.Object); - - if (filterFactory) - { - propertyFilter.FilterFactory = new Mock().Object; - } - - return propertyFilter; - } - - public class TestPageString : Page - { - [TempData] - public string Test { get; set; } - - [TempData] - public string Test2 { get; set; } - - public override Task ExecuteAsync() - { - throw new NotImplementedException(); - } - } - - public class TestPageStringWithModel : Page - { - public PageModel TestPageModelWithString { get; set; } - - public override Task ExecuteAsync() - { - throw new NotImplementedException(); - } - } - - public class TestPageModelWithString : PageModel - { - [TempData] - public string Test { get; set; } - - [TempData] - public string Test2 { get; set; } - } - } -} diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/SaveTempDataFilterTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilterTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilter/SaveTempDataFilterTest.cs rename to test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Internal/SaveTempDataFilterTest.cs