1161 lines
55 KiB
C#
1161 lines
55 KiB
C#
|
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|||
|
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Globalization;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using System.Net;
|
|||
|
using System.Threading;
|
|||
|
using System.Web.Routing;
|
|||
|
using System.Web.UI.WebControls;
|
|||
|
using Microsoft.Web.UnitTestUtil;
|
|||
|
using Moq;
|
|||
|
using Xunit;
|
|||
|
using Assert = Microsoft.TestCommon.AssertEx;
|
|||
|
|
|||
|
namespace System.Web.Mvc.Html.Test
|
|||
|
{
|
|||
|
public class TemplateHelpersTest
|
|||
|
{
|
|||
|
// ExecuteTemplate
|
|||
|
|
|||
|
private class ExecuteTemplateModel
|
|||
|
{
|
|||
|
public string MyProperty { get; set; }
|
|||
|
public Nullable<int> MyNullableProperty { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateCallsGetViewNamesWithProvidedTemplateNameAndMetadataInformation()
|
|||
|
{
|
|||
|
using (new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.TemplateHint = "templateHint";
|
|||
|
metadata.DataTypeName = "dataType";
|
|||
|
string[] hints = null;
|
|||
|
|
|||
|
// Act
|
|||
|
TemplateHelpers.ExecuteTemplate(
|
|||
|
html, MakeViewData(html, metadata), "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
(_metadata, _hints) =>
|
|||
|
{
|
|||
|
hints = _hints;
|
|||
|
return new[] { "String" };
|
|||
|
},
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(hints);
|
|||
|
Assert.Equal(3, hints.Length);
|
|||
|
Assert.Equal("templateName", hints[0]);
|
|||
|
Assert.Equal("templateHint", hints[1]);
|
|||
|
Assert.Equal("dataType", hints[2]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateUsesViewFromViewEngineInReadOnlyMode()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewContext callbackViewContext = null;
|
|||
|
engine.Engine.Setup(e => e.FindPartialView(html.ViewContext, "DisplayTemplates/String", true))
|
|||
|
.Returns(new ViewEngineResult(engine.View.Object, engine.Engine.Object))
|
|||
|
.Verifiable();
|
|||
|
engine.View.Setup(v => v.Render(It.IsAny<ViewContext>(), It.IsAny<TextWriter>()))
|
|||
|
.Callback<ViewContext, TextWriter>((vc, tw) =>
|
|||
|
{
|
|||
|
callbackViewContext = vc;
|
|||
|
tw.Write("View Text");
|
|||
|
})
|
|||
|
.Verifiable();
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
engine.Engine.Verify();
|
|||
|
engine.View.Verify();
|
|||
|
Assert.Equal("View Text", result);
|
|||
|
Assert.Same(engine.View.Object, callbackViewContext.View);
|
|||
|
Assert.Same(viewData, callbackViewContext.ViewData);
|
|||
|
Assert.Same(html.ViewContext.TempData, callbackViewContext.TempData);
|
|||
|
TemplateHelpers.ActionCacheViewItem cacheItem = TemplateHelpers.GetActionCache(html)["DisplayTemplates/String"] as TemplateHelpers.ActionCacheViewItem;
|
|||
|
Assert.NotNull(cacheItem);
|
|||
|
Assert.Equal("DisplayTemplates/String", cacheItem.ViewName);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateUsesViewFromViewEngineInEditMode()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewContext callbackViewContext = null;
|
|||
|
engine.Engine.Setup(e => e.FindPartialView(html.ViewContext, "EditorTemplates/String", true))
|
|||
|
.Returns(new ViewEngineResult(engine.View.Object, engine.Engine.Object))
|
|||
|
.Verifiable();
|
|||
|
engine.View.Setup(v => v.Render(It.IsAny<ViewContext>(), It.IsAny<TextWriter>()))
|
|||
|
.Callback<ViewContext, TextWriter>((vc, tw) =>
|
|||
|
{
|
|||
|
callbackViewContext = vc;
|
|||
|
tw.Write("View Text");
|
|||
|
})
|
|||
|
.Verifiable();
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.Edit,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
engine.Engine.Verify();
|
|||
|
engine.View.Verify();
|
|||
|
Assert.Equal("View Text", result);
|
|||
|
Assert.Same(engine.View.Object, callbackViewContext.View);
|
|||
|
Assert.Same(viewData, callbackViewContext.ViewData);
|
|||
|
Assert.Same(html.ViewContext.TempData, callbackViewContext.TempData);
|
|||
|
TemplateHelpers.ActionCacheViewItem cacheItem = TemplateHelpers.GetActionCache(html)["EditorTemplates/String"] as TemplateHelpers.ActionCacheViewItem;
|
|||
|
Assert.NotNull(cacheItem);
|
|||
|
Assert.Equal("EditorTemplates/String", cacheItem.ViewName);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateUsesViewFromDefaultActionsInReadOnlyMode()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
engine.Engine.Setup(e => e.FindPartialView(html.ViewContext, "DisplayTemplates/String", It.IsAny<bool>()))
|
|||
|
.Returns(new ViewEngineResult(new string[0]))
|
|||
|
.Verifiable();
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
|
|||
|
// Act
|
|||
|
TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
engine.Engine.Verify();
|
|||
|
TemplateHelpers.ActionCacheCodeItem cacheItem = TemplateHelpers.GetActionCache(html)["DisplayTemplates/String"] as TemplateHelpers.ActionCacheCodeItem;
|
|||
|
Assert.NotNull(cacheItem);
|
|||
|
Assert.Equal(DefaultDisplayTemplates.StringTemplate, cacheItem.Action);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateUsesViewFromDefaultActionsInEditMode()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
engine.Engine.Setup(e => e.FindPartialView(html.ViewContext, "EditorTemplates/String", It.IsAny<bool>()))
|
|||
|
.Returns(new ViewEngineResult(new string[0]))
|
|||
|
.Verifiable();
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
|
|||
|
// Act
|
|||
|
TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.Edit,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
engine.Engine.Verify();
|
|||
|
TemplateHelpers.ActionCacheCodeItem cacheItem = TemplateHelpers.GetActionCache(html)["EditorTemplates/String"] as TemplateHelpers.ActionCacheCodeItem;
|
|||
|
Assert.NotNull(cacheItem);
|
|||
|
Assert.Equal(DefaultEditorTemplates.StringTemplate, cacheItem.Action);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplatePrefersExistingActionCacheItem()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
TemplateHelpers.GetActionCache(html).Add("EditorTemplates/String",
|
|||
|
new TemplateHelpers.ActionCacheCodeItem { Action = _ => "Action Text" });
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.Edit,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
engine.Engine.Verify();
|
|||
|
engine.Engine.Verify(e => e.FindPartialView(It.IsAny<ControllerContext>(), It.IsAny<string>(), It.IsAny<bool>()), Times.Never());
|
|||
|
Assert.Equal("Action Text", result);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateThrowsWhenNoTemplatesMatch()
|
|||
|
{
|
|||
|
using (new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
|
|||
|
// Act & Assert
|
|||
|
Assert.Throws<InvalidOperationException>(
|
|||
|
() => TemplateHelpers.ExecuteTemplate(html, viewData, "templateName", DataBoundControlMode.Edit, delegate { return new string[0]; }, TemplateHelpers.GetDefaultActions),
|
|||
|
"Unable to locate an appropriate template for type System.String.");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateCreatesNewHtmlHelperWithCorrectViewDataForDefaultAction()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine(false))
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
HtmlHelper passedHtmlHelper = null;
|
|||
|
|
|||
|
// Act
|
|||
|
TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.Edit,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
delegate
|
|||
|
{
|
|||
|
return new Dictionary<string, Func<HtmlHelper, string>>
|
|||
|
{
|
|||
|
{
|
|||
|
"String", _htmlHelper =>
|
|||
|
{
|
|||
|
passedHtmlHelper = _htmlHelper;
|
|||
|
return "content";
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
});
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(passedHtmlHelper);
|
|||
|
Assert.Same(passedHtmlHelper.ViewData, passedHtmlHelper.ViewContext.ViewData);
|
|||
|
Assert.NotSame(html.ViewData, passedHtmlHelper.ViewData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void ExecuteTemplateCreatesNewHtmlHelperWithCorrectViewDataForCachedAction()
|
|||
|
{
|
|||
|
using (MockViewEngine engine = new MockViewEngine())
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new ExecuteTemplateModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary viewData = MakeViewData(html, metadata);
|
|||
|
HtmlHelper passedHtmlHelper = null;
|
|||
|
TemplateHelpers.GetActionCache(html).Add(
|
|||
|
"EditorTemplates/String",
|
|||
|
new TemplateHelpers.ActionCacheCodeItem
|
|||
|
{
|
|||
|
Action = _htmlHelper =>
|
|||
|
{
|
|||
|
passedHtmlHelper = _htmlHelper;
|
|||
|
return "content";
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.ExecuteTemplate(
|
|||
|
html, viewData, "templateName", DataBoundControlMode.Edit,
|
|||
|
delegate { return new[] { "String" }; },
|
|||
|
TemplateHelpers.GetDefaultActions);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(passedHtmlHelper);
|
|||
|
Assert.Same(passedHtmlHelper.ViewData, passedHtmlHelper.ViewContext.ViewData);
|
|||
|
Assert.NotSame(html.ViewData, passedHtmlHelper.ViewData);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// GetActionCache
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void CacheIsCreatedIfNotPresent()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
Hashtable items = new Hashtable();
|
|||
|
Mock<HttpContextBase> context = new Mock<HttpContextBase>();
|
|||
|
context.Setup(c => c.Items).Returns(items);
|
|||
|
Mock<ViewContext> viewContext = new Mock<ViewContext>();
|
|||
|
viewContext.Setup(c => c.HttpContext).Returns(context.Object);
|
|||
|
Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
|
|||
|
HtmlHelper helper = new HtmlHelper(viewContext.Object, viewDataContainer.Object);
|
|||
|
|
|||
|
// Act
|
|||
|
Dictionary<string, TemplateHelpers.ActionCacheItem> cache = TemplateHelpers.GetActionCache(helper);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(cache);
|
|||
|
Assert.Empty(cache);
|
|||
|
Assert.Contains((object)cache, items.Values.OfType<object>());
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void CacheIsReusedIfPresent()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
Hashtable items = new Hashtable();
|
|||
|
Mock<HttpContextBase> context = new Mock<HttpContextBase>();
|
|||
|
context.Setup(c => c.Items).Returns(items);
|
|||
|
Mock<ViewContext> viewContext = new Mock<ViewContext>();
|
|||
|
viewContext.Setup(c => c.HttpContext).Returns(context.Object);
|
|||
|
Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
|
|||
|
HtmlHelper helper = new HtmlHelper(viewContext.Object, viewDataContainer.Object);
|
|||
|
|
|||
|
// Act
|
|||
|
Dictionary<string, TemplateHelpers.ActionCacheItem> cache1 = TemplateHelpers.GetActionCache(helper);
|
|||
|
Dictionary<string, TemplateHelpers.ActionCacheItem> cache2 = TemplateHelpers.GetActionCache(helper);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(cache1);
|
|||
|
Assert.Same(cache1, cache2);
|
|||
|
}
|
|||
|
|
|||
|
// GetViewNames
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesFullOrderingOfBuiltInValueType()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(double));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, "UIHint", "DataType").ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(4, result.Count);
|
|||
|
Assert.Equal("UIHint", result[0]);
|
|||
|
Assert.Equal("DataType", result[1]);
|
|||
|
Assert.Equal("Double", result[2]);
|
|||
|
Assert.Equal("String", result[3]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesFullOrderingOfComplexType()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(HttpWebRequest));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, "UIHint", "DataType").ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(6, result.Count);
|
|||
|
Assert.Equal("UIHint", result[0]);
|
|||
|
Assert.Equal("DataType", result[1]);
|
|||
|
Assert.Equal("HttpWebRequest", result[2]);
|
|||
|
Assert.Equal("WebRequest", result[3]);
|
|||
|
Assert.Equal("MarshalByRefObject", result[4]);
|
|||
|
Assert.Equal("Object", result[5]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesFullOrderingOfInterface()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(IDisposable));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, "UIHint", "DataType").ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(4, result.Count);
|
|||
|
Assert.Equal("UIHint", result[0]);
|
|||
|
Assert.Equal("DataType", result[1]);
|
|||
|
Assert.Equal("IDisposable", result[2]);
|
|||
|
Assert.Equal("Object", result[3]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesFullOrderingOfComplexTypeThatImplementsIEnumerable()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(List<int>));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, "UIHint", "DataType").ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(5, result.Count);
|
|||
|
Assert.Equal("UIHint", result[0]);
|
|||
|
Assert.Equal("DataType", result[1]);
|
|||
|
Assert.Equal("List`1", result[2]);
|
|||
|
Assert.Equal("Collection", result[3]);
|
|||
|
Assert.Equal("Object", result[4]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesFullOrderingOfInterfaceThatRequiresIEnumerable()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(IList<int>));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, "UIHint", "DataType").ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(5, result.Count);
|
|||
|
Assert.Equal("UIHint", result[0]);
|
|||
|
Assert.Equal("DataType", result[1]);
|
|||
|
Assert.Equal("IList`1", result[2]);
|
|||
|
Assert.Equal("Collection", result[3]);
|
|||
|
Assert.Equal("Object", result[4]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesNullUIHintNotIncludedInList()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(Object));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, null, "DataType").ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(2, result.Count);
|
|||
|
Assert.Equal("DataType", result[0]);
|
|||
|
Assert.Equal("Object", result[1]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesNullDataTypeNotIncludedInList()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(Object));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, "UIHint", null).ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(2, result.Count);
|
|||
|
Assert.Equal("UIHint", result[0]);
|
|||
|
Assert.Equal("Object", result[1]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void GetViewNamesConvertsNullableOfTIntoT()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(Nullable<int>));
|
|||
|
|
|||
|
// Act
|
|||
|
List<string> result = TemplateHelpers.GetViewNames(metadata, null, null).ToList();
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(2, result.Count);
|
|||
|
Assert.Equal("Int32", result[0]);
|
|||
|
Assert.Equal("String", result[1]);
|
|||
|
}
|
|||
|
|
|||
|
// Template
|
|||
|
|
|||
|
private class TemplateModel
|
|||
|
{
|
|||
|
public object MyProperty { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateNullExpressionThrows()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<object> html = MakeHtmlHelper<object>(null);
|
|||
|
|
|||
|
// Act & Assert
|
|||
|
Assert.ThrowsArgumentNull(
|
|||
|
() => TemplateHelpers.Template(html, null, "templateName", "htmlFieldName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy),
|
|||
|
"expression");
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateDataNotFound()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<object> html = MakeHtmlHelper<object>(null);
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.Template(html, "UnknownObject", "templateName", null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = (null), HtmlFieldName = UnknownObject, TemplateName = templateName, Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHtmlFieldNameReplacesExpression()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<object> html = MakeHtmlHelper<object>(null);
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.Template(html, "UnknownObject", "templateName", "htmlFieldName", DataBoundControlMode.ReadOnly,
|
|||
|
new { foo = "Bar" }, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = (null), HtmlFieldName = htmlFieldName, TemplateName = templateName, Mode = ReadOnly, AdditionalViewData = { foo: Bar }", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateDataFoundInViewDataDictionaryHasNoPropertyName()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<object> html = MakeHtmlHelper<object>(null);
|
|||
|
html.ViewContext.ViewData["Key"] = 42;
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.Template(html, "Key", null, null, DataBoundControlMode.Edit, null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = 42, ModelType = System.Int32, RealModelType = System.Int32, PropertyName = (null), HtmlFieldName = Key, TemplateName = (null), Mode = Edit, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateDataFoundInViewDataDictionarySubPropertyHasPropertyName()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<object> html = MakeHtmlHelper<object>(null);
|
|||
|
html.ViewContext.ViewData["Key"] = new TemplateModel { MyProperty = "Hello!" };
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.Template(html, "Key.MyProperty", null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello!, ModelType = System.Object, RealModelType = System.String, PropertyName = MyProperty, HtmlFieldName = Key.MyProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateDataFoundInModelHasPropertyName()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateModel> html = MakeHtmlHelper<TemplateModel>(new TemplateModel { MyProperty = "Hello!" });
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.Template(html, "MyProperty", null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello!, ModelType = System.Object, RealModelType = System.String, PropertyName = MyProperty, HtmlFieldName = MyProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateNullDataFoundInModelHasPropertyTypeInsteadOfActualModelType()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateModel> html = MakeHtmlHelper<TemplateModel>(new TemplateModel());
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.Template(html, "MyProperty", null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.Object, RealModelType = System.Object, PropertyName = MyProperty, HtmlFieldName = MyProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
// TemplateFor
|
|||
|
|
|||
|
private class TemplateForModel
|
|||
|
{
|
|||
|
public int MyField = 0;
|
|||
|
public object MyProperty { get; set; }
|
|||
|
public Nullable<int> MyNullableProperty { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForNonUnsupportedExpressionTypeThrows()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper<TemplateForModel>(null);
|
|||
|
|
|||
|
// Act & Assert
|
|||
|
Assert.Throws<InvalidOperationException>(
|
|||
|
() => TemplateHelpers.TemplateFor(html, model => new Object(), "templateName", "htmlFieldName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy),
|
|||
|
"Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.");
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForWithNonNullExpression()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel { MyProperty = "Hello!" });
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyProperty, "templateName", null, DataBoundControlMode.ReadOnly,
|
|||
|
new { foo = "Bar" }, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello!, ModelType = System.Object, RealModelType = System.String, PropertyName = MyProperty, HtmlFieldName = MyProperty, TemplateName = templateName, Mode = ReadOnly, AdditionalViewData = { foo: Bar }", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForHtmlFieldNameReplacesExpression()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel { MyProperty = "Hello!" });
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyProperty, "templateName", "htmlFieldName",
|
|||
|
DataBoundControlMode.ReadOnly, null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello!, ModelType = System.Object, RealModelType = System.String, PropertyName = MyProperty, HtmlFieldName = htmlFieldName, TemplateName = templateName, Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForNullModelStillRetainsTypeInformation()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper<TemplateForModel>(null);
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyProperty, null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.Object, RealModelType = System.Object, PropertyName = MyProperty, HtmlFieldName = MyProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForNullPropertyStillRetainsTypeInformation()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel());
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyProperty, null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.Object, RealModelType = System.Object, PropertyName = MyProperty, HtmlFieldName = MyProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForNullableValueTYpePropertyRetainsNullableValueTYpeForNullPropertyValue()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel());
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyNullableProperty, null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], RealModelType = System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], PropertyName = MyNullableProperty, HtmlFieldName = MyNullableProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForNullableValueTypePropertyRetainsNullableValueTypeForNonNullPropertyValue()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel { MyNullableProperty = 42 });
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyNullableProperty, null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = 42, ModelType = System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], RealModelType = System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], PropertyName = MyNullableProperty, HtmlFieldName = MyNullableProperty, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForWithParameterExpression()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel());
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model, null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = System.Web.Mvc.Html.Test.TemplateHelpersTest+TemplateForModel, ModelType = System.Web.Mvc.Html.Test.TemplateHelpersTest+TemplateForModel, RealModelType = System.Web.Mvc.Html.Test.TemplateHelpersTest+TemplateForModel, PropertyName = (null), HtmlFieldName = (empty), TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateForWithFieldExpression()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper<TemplateForModel> html = MakeHtmlHelper(new TemplateForModel { MyField = 42 });
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateFor(html, model => model.MyField, null, null, DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, TemplateHelperSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = 42, ModelType = System.Int32, RealModelType = System.Int32, PropertyName = (null), HtmlFieldName = MyField, TemplateName = (null), Mode = ReadOnly, AdditionalViewData = (null)", result);
|
|||
|
}
|
|||
|
|
|||
|
// TemplateHelper
|
|||
|
|
|||
|
private class TemplateHelperModel
|
|||
|
{
|
|||
|
public string MyProperty { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperNonNullNonEmptyStringModel()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello, ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = Hello, HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperEmptyStringModel()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.ConvertEmptyStringToNull = false;
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = , ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = , HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperConvertsEmptyStringsToNull()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.ConvertEmptyStringToNull = true;
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = , HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperConvertsNullModelsToNullDisplayTextInReadOnlyMode()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.NullDisplayText = "NullDisplayText";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = NullDisplayText, HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperDoesNotConvertNullModelsToNullDisplayTextInEditMode()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.NullDisplayText = "NullDisplayText";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.Edit,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = , HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = Edit", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperAppliesDisplayFormatStringInReadOnlyMode()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.DisplayFormatString = "{0} world!";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello, ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = Hello world!, HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperDoesNotApplyDisplayFormatStringInReadOnlyModeForNullModel()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.DisplayFormatString = "{0} world!";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = , HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperAppliesEditFormatStringInEditMode()
|
|||
|
{
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.EditFormatString = "{0} world!";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.Edit,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = Hello, ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = Hello world!, HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = Edit", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperDoesNotApplyEditFormatStringInEditModeForNullModel()
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.EditFormatString = "{0} world!";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.Edit,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = (null), ModelType = System.String, RealModelType = System.String, PropertyName = MyProperty, FormattedModelValue = , HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = Edit", result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperAddsNonNullModelToVisitedObjects()
|
|||
|
{ // DDB #224750
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary viewData = null;
|
|||
|
|
|||
|
// Act
|
|||
|
TemplateHelpers.TemplateHelper(
|
|||
|
html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly, null /* additionalViewData */,
|
|||
|
(_html, _viewData, _templateName, _mode, _getViews, _getDefaultActions) =>
|
|||
|
{
|
|||
|
viewData = _viewData;
|
|||
|
return String.Empty;
|
|||
|
});
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(viewData);
|
|||
|
Assert.True(viewData.TemplateInfo.VisitedObjects.Contains("Hello"));
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperAddsNullModelsTypeToVisitedObjects()
|
|||
|
{ // DDB #224750
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary viewData = null;
|
|||
|
|
|||
|
// Act
|
|||
|
TemplateHelpers.TemplateHelper(
|
|||
|
html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly, null /* additionalViewData */,
|
|||
|
(_html, _viewData, _templateName, _mode, _getViews, _getDefaultActions) =>
|
|||
|
{
|
|||
|
viewData = _viewData;
|
|||
|
return String.Empty;
|
|||
|
});
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(viewData);
|
|||
|
Assert.True(viewData.TemplateInfo.VisitedObjects.Contains(typeof(string)));
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperReturnsEmptyStringForAlreadyVisitedObject()
|
|||
|
{ // DDB #224750
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel { MyProperty = "Hello" });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
html.ViewData.TemplateInfo.VisitedObjects.Add("Hello");
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(String.Empty, result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperReturnsEmptyStringForAlreadyVisitedType()
|
|||
|
{ // DDB #224750
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
html.ViewData.TemplateInfo.VisitedObjects.Add(typeof(string));
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal(String.Empty, result);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperPreservesSameInstanceOfModelMetadata()
|
|||
|
{ // DDB #225858
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary callbackViewData = null;
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */,
|
|||
|
(_html, _viewData, _templateName, _mode, _getViewNames, _getDefaultActions) =>
|
|||
|
{
|
|||
|
callbackViewData = _viewData;
|
|||
|
return String.Empty;
|
|||
|
});
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotNull(callbackViewData);
|
|||
|
Assert.Same(metadata, callbackViewData.ModelMetadata);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperFormatsValuesUsingCurrentCulture()
|
|||
|
{
|
|||
|
CultureInfo existingCulture = Thread.CurrentThread.CurrentCulture;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
// Arrange
|
|||
|
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("es-PR");
|
|||
|
HtmlHelper html = MakeHtmlHelper(new { MyProperty = new DateTime(2009, 11, 18, 16, 12, 8, DateTimeKind.Utc) });
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
metadata.DisplayFormatString = "{0:F}";
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */, ExecuteTemplateSpy);
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.Equal("Model = 18/11/2009 04:12:08 p.m., ModelType = System.DateTime, RealModelType = System.DateTime, PropertyName = MyProperty, FormattedModelValue = miércoles, 18 de noviembre de 2009 04:12:08 p.m., HtmlFieldPrefix = FieldPrefix.htmlFieldName, TemplateName = templateName, Mode = ReadOnly", result);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
Thread.CurrentThread.CurrentCulture = existingCulture;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperPreservesExistingViewData()
|
|||
|
{
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
html.ViewData["Foo"] = "Bar";
|
|||
|
html.ViewData["Baz"] = 42;
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary callbackViewData = null;
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
null /* additionalViewData */,
|
|||
|
(_html, _viewData, _templateName, _mode, _getViewNames, _getDefaultActions) =>
|
|||
|
{
|
|||
|
callbackViewData = _viewData;
|
|||
|
return String.Empty;
|
|||
|
});
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotSame(html.ViewData, callbackViewData);
|
|||
|
Assert.Equal(2, callbackViewData.Count);
|
|||
|
Assert.Equal("Bar", callbackViewData["Foo"]);
|
|||
|
Assert.Equal(42, callbackViewData["Baz"]);
|
|||
|
}
|
|||
|
|
|||
|
[Fact]
|
|||
|
public void TemplateHelperMergesAdditionalViewData()
|
|||
|
{
|
|||
|
HtmlHelper html = MakeHtmlHelper(new TemplateHelperModel());
|
|||
|
html.ViewData["Foo"] = "Bar";
|
|||
|
html.ViewData["Baz"] = 42;
|
|||
|
ModelMetadata metadata = ModelMetadata.FromStringExpression("MyProperty", html.ViewData);
|
|||
|
ViewDataDictionary callbackViewData = null;
|
|||
|
|
|||
|
// Act
|
|||
|
string result = TemplateHelpers.TemplateHelper(html, metadata, "htmlFieldName", "templateName", DataBoundControlMode.ReadOnly,
|
|||
|
new { foo = "New Foo", hello = "World!" },
|
|||
|
(_html, _viewData, _templateName, _mode, _getViewNames, _getDefaultActions) =>
|
|||
|
{
|
|||
|
callbackViewData = _viewData;
|
|||
|
return String.Empty;
|
|||
|
});
|
|||
|
|
|||
|
// Assert
|
|||
|
Assert.NotSame(html.ViewData, callbackViewData);
|
|||
|
Assert.Equal(3, callbackViewData.Count);
|
|||
|
Assert.Equal("New Foo", callbackViewData["Foo"]);
|
|||
|
Assert.Equal(42, callbackViewData["Baz"]);
|
|||
|
Assert.Equal("World!", callbackViewData["Hello"]);
|
|||
|
}
|
|||
|
|
|||
|
// Helpers
|
|||
|
|
|||
|
private static string ExecuteTemplateSpy(HtmlHelper html, ViewDataDictionary viewData, string templateName, DataBoundControlMode mode,
|
|||
|
TemplateHelpers.GetViewNamesDelegate getViewNames, TemplateHelpers.GetDefaultActionsDelegate getDefaultActions)
|
|||
|
{
|
|||
|
Assert.Same(viewData.Model, viewData.ModelMetadata.Model);
|
|||
|
Assert.Equal<TemplateHelpers.GetViewNamesDelegate>(TemplateHelpers.GetViewNames, getViewNames);
|
|||
|
Assert.Equal<TemplateHelpers.GetDefaultActionsDelegate>(TemplateHelpers.GetDefaultActions, getDefaultActions);
|
|||
|
|
|||
|
return String.Format("Model = {0}, ModelType = {1}, RealModelType = {2}, PropertyName = {3}, FormattedModelValue = {4}, HtmlFieldPrefix = {5}, TemplateName = {6}, Mode = {7}",
|
|||
|
viewData.ModelMetadata.Model ?? "(null)",
|
|||
|
viewData.ModelMetadata.ModelType == null ? "(null)" : viewData.ModelMetadata.ModelType.FullName,
|
|||
|
viewData.ModelMetadata.RealModelType == null ? "(null)" : viewData.ModelMetadata.RealModelType.FullName,
|
|||
|
viewData.ModelMetadata.PropertyName ?? "(null)",
|
|||
|
viewData.TemplateInfo.FormattedModelValue ?? "(null)",
|
|||
|
viewData.TemplateInfo.HtmlFieldPrefix == "" ? "(empty)" : viewData.TemplateInfo.HtmlFieldPrefix ?? "(null)",
|
|||
|
templateName ?? "(null)",
|
|||
|
mode);
|
|||
|
}
|
|||
|
|
|||
|
private static string TemplateHelperSpy(HtmlHelper html, ModelMetadata metadata, string htmlFieldName, string templateName, DataBoundControlMode mode,
|
|||
|
object additionalViewData)
|
|||
|
{
|
|||
|
return String.Format("Model = {0}, ModelType = {1}, RealModelType = {2}, PropertyName = {3}, HtmlFieldName = {4}, TemplateName = {5}, Mode = {6}, AdditionalViewData = {7}",
|
|||
|
metadata.Model ?? "(null)",
|
|||
|
metadata.ModelType == null ? "(null)" : metadata.ModelType.FullName,
|
|||
|
metadata.RealModelType == null ? "(null)" : metadata.RealModelType.FullName,
|
|||
|
metadata.PropertyName ?? "(null)",
|
|||
|
htmlFieldName == String.Empty ? "(empty)" : htmlFieldName ?? "(null)",
|
|||
|
templateName ?? "(null)",
|
|||
|
mode,
|
|||
|
AnonymousObject.Inspect(additionalViewData));
|
|||
|
}
|
|||
|
|
|||
|
private HtmlHelper<TModel> MakeHtmlHelper<TModel>(TModel model)
|
|||
|
{
|
|||
|
return MakeHtmlHelper<TModel>(model, model);
|
|||
|
}
|
|||
|
|
|||
|
private HtmlHelper<TModel> MakeHtmlHelper<TModel>(TModel model, object formattedModelValue)
|
|||
|
{
|
|||
|
ViewDataDictionary viewData = new ViewDataDictionary(model);
|
|||
|
viewData.TemplateInfo.HtmlFieldPrefix = "FieldPrefix";
|
|||
|
viewData.TemplateInfo.FormattedModelValue = formattedModelValue;
|
|||
|
viewData.ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => model, typeof(TModel));
|
|||
|
|
|||
|
Mock<HttpContextBase> httpContext = new Mock<HttpContextBase>();
|
|||
|
httpContext.Setup(c => c.Items).Returns(new Hashtable());
|
|||
|
|
|||
|
Mock<ViewContext> viewContext = new Mock<ViewContext> { CallBase = true };
|
|||
|
viewContext.Setup(c => c.View).Returns(new DummyView());
|
|||
|
viewContext.Setup(c => c.ViewData).Returns(viewData);
|
|||
|
viewContext.Setup(c => c.HttpContext).Returns(httpContext.Object);
|
|||
|
viewContext.Setup(c => c.RouteData).Returns(new RouteData());
|
|||
|
viewContext.Setup(c => c.TempData).Returns(new TempDataDictionary());
|
|||
|
viewContext.Setup(c => c.Writer).Returns(TextWriter.Null);
|
|||
|
|
|||
|
return new HtmlHelper<TModel>(viewContext.Object, new SimpleViewDataContainer(viewData));
|
|||
|
}
|
|||
|
|
|||
|
private ViewDataDictionary MakeViewData(HtmlHelper html, ModelMetadata metadata)
|
|||
|
{
|
|||
|
return new ViewDataDictionary(html.ViewDataContainer.ViewData)
|
|||
|
{
|
|||
|
Model = metadata.Model,
|
|||
|
ModelMetadata = metadata,
|
|||
|
TemplateInfo = new TemplateInfo
|
|||
|
{
|
|||
|
FormattedModelValue = metadata.Model,
|
|||
|
HtmlFieldPrefix = "FieldPrefix",
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
private class DummyView : IView
|
|||
|
{
|
|||
|
public void Render(ViewContext viewContext, TextWriter writer)
|
|||
|
{
|
|||
|
throw new NotImplementedException();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private class MockViewEngine : IDisposable
|
|||
|
{
|
|||
|
List<IViewEngine> oldEngines;
|
|||
|
|
|||
|
public MockViewEngine(bool returnView = true)
|
|||
|
{
|
|||
|
oldEngines = ViewEngines.Engines.ToList();
|
|||
|
|
|||
|
View = new Mock<IView>();
|
|||
|
|
|||
|
Engine = new Mock<IViewEngine>();
|
|||
|
|
|||
|
Engine.Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), It.IsAny<string>(), It.IsAny<bool>()))
|
|||
|
.Returns(returnView ? new ViewEngineResult(View.Object, Engine.Object) : new ViewEngineResult(new string[0]));
|
|||
|
|
|||
|
ViewEngines.Engines.Clear();
|
|||
|
ViewEngines.Engines.Add(Engine.Object);
|
|||
|
}
|
|||
|
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
ViewEngines.Engines.Clear();
|
|||
|
|
|||
|
foreach (IViewEngine engine in oldEngines)
|
|||
|
{
|
|||
|
ViewEngines.Engines.Add(engine);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public Mock<IViewEngine> Engine { get; set; }
|
|||
|
|
|||
|
public Mock<IView> View { get; set; }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|