// 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 Microsoft.AspNetCore.Mvc.ModelBinding; using Xunit; namespace Microsoft.AspNetCore.Mvc.Rendering { /// /// Test the class. /// public class HtmlHelperDisplayNameExtensionsTest { [Fact] public void DisplayNameHelpers_ReturnEmptyForModel() { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper(); var enumerableHelper = DefaultTemplatesUtilities.GetHtmlHelper>(model: null); // Act var displayNameResult = helper.DisplayName(expression: string.Empty); var displayNameNullResult = helper.DisplayName(expression: null); // null is another alias for current model var displayNameForResult = helper.DisplayNameFor(m => m); var displayNameForEnumerableModelResult = enumerableHelper.DisplayNameFor(m => m); var displayNameForModelResult = helper.DisplayNameForModel(); // Assert Assert.Empty(displayNameResult); Assert.Empty(displayNameNullResult); Assert.Empty(displayNameForResult); Assert.Empty(displayNameForEnumerableModelResult); Assert.Empty(displayNameForModelResult); } [Fact] public void DisplayNameHelpers_ReturnPropertyName() { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper(); var enumerableHelper = DefaultTemplatesUtilities.GetHtmlHelperForEnumerable(); // Act var displayNameResult = helper.DisplayName("Property1"); var displayNameForResult = helper.DisplayNameFor(m => m.Property1); var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Property1); // Assert Assert.Equal("Property1", displayNameResult); Assert.Equal("Property1", displayNameForResult); Assert.Equal("Property1", displayNameForEnumerableResult); } // If the metadata is for a type (not property), then DisplayName(expression) will evaluate the expression [Fact] public void DisplayNameHelpers_DisplayName_Evaluates_Expression() { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper(); helper.ViewData["value"] = "testvalue"; // Act var displayNameResult = helper.DisplayName(expression: "value"); // Assert Assert.Equal("value", displayNameResult); } [Fact] public void DisplayNameHelpers_ReturnPropertyName_ForNestedProperty() { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper(model: null); var enumerableHelper = DefaultTemplatesUtilities.GetHtmlHelperForEnumerable(model: null); // Act var displayNameResult = helper.DisplayName("Inner.Id"); var displayNameForResult = helper.DisplayNameFor(m => m.Inner.Id); var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Inner.Id); // Assert Assert.Equal("Id", displayNameResult); Assert.Equal("Id", displayNameForResult); Assert.Equal("Id", displayNameForEnumerableResult); } [Theory] [InlineData("")] // Empty display name wins over non-empty property name. [InlineData("Custom display name from metadata")] public void DisplayNameHelpers_ReturnDisplayName_IfNonNull(string displayName) { // Arrange var provider = new TestModelMetadataProvider(); provider .ForType() .DisplayDetails(dd => dd.DisplayName = () => displayName); var helper = DefaultTemplatesUtilities.GetHtmlHelper(provider: provider); var enumerableHelper = DefaultTemplatesUtilities.GetHtmlHelperForEnumerable(provider: provider); // Act var displayNameResult = helper.DisplayName(expression: string.Empty); var displayNameForResult = helper.DisplayNameFor(m => m); var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor((DefaultTemplatesUtilities.ObjectTemplateModel m) => m); var displayNameForModelResult = helper.DisplayNameForModel(); // Assert Assert.Equal(displayName, displayNameResult); Assert.Equal(displayName, displayNameForResult); Assert.Equal(displayName, displayNameForEnumerableResult); Assert.Equal(displayName, displayNameForModelResult); } [Theory] [InlineData("")] [InlineData("Custom display name from metadata")] public void DisplayNameHelpers_ReturnDisplayNameForProperty_IfNonNull(string displayName) { // Arrange var provider = new TestModelMetadataProvider(); provider .ForProperty("Property1") .DisplayDetails(dd => dd.DisplayName = () => displayName); var helper = DefaultTemplatesUtilities.GetHtmlHelper(provider: provider); var enumerableHelper = DefaultTemplatesUtilities.GetHtmlHelperForEnumerable(provider: provider); // Act var displayNameResult = helper.DisplayName("Property1"); var displayNameForResult = helper.DisplayNameFor(m => m.Property1); var displayNameForEnumerableResult = enumerableHelper.DisplayNameFor(m => m.Property1); // Assert Assert.Equal(displayName, displayNameResult); Assert.Equal(displayName, displayNameForResult); Assert.Equal(displayName, displayNameForEnumerableResult); } [Theory] [InlineData("A", "A")] [InlineData("A[23]", "A[23]")] [InlineData("A[0].B", "B")] [InlineData("A.B.C.D", "D")] public void DisplayName_ReturnsRightmostExpressionSegment_IfPropertiesNotFound( string expression, string expectedResult) { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper(); // Act var result = helper.DisplayName(expression); // Assert // DisplayName() falls back to expression name when DisplayName and PropertyName are null. Assert.Equal(expectedResult, result); } [Fact] public void DisplayNameFor_ThrowsInvalidOperation_IfExpressionUnsupported() { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper(); // Act & Assert var exception = Assert.Throws( () => helper.DisplayNameFor(model => new { foo = "Bar" })); Assert.Equal( "Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.", exception.Message); } [Fact] public void EnumerableDisplayNameFor_ThrowsInvalidOperation_IfExpressionUnsupported() { // Arrange var helper = DefaultTemplatesUtilities.GetHtmlHelper>(model: null); // Act & Assert var exception = Assert.Throws( () => helper.DisplayNameFor(model => new { foo = "Bar" })); Assert.Equal( "Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.", exception.Message); } [Fact] public void DisplayNameFor_ReturnsVariableName() { // Arrange var unknownKey = "this is a dummy parameter value"; var helper = DefaultTemplatesUtilities.GetHtmlHelper(); // Act var result = helper.DisplayNameFor(model => unknownKey); // Assert Assert.Equal("unknownKey", result); } [Fact] public void EnumerableDisplayNameFor_ReturnsVariableName() { // Arrange var unknownKey = "this is a dummy parameter value"; var helper = DefaultTemplatesUtilities.GetHtmlHelper>(model: null); // Act var result = helper.DisplayNameFor(model => unknownKey); // Assert Assert.Equal("unknownKey", result); } private sealed class InnerClass { public int Id { get; set; } } private sealed class OuterClass { public InnerClass Inner { get; set; } } } }