1089 lines
44 KiB
C#
Raw Normal View History

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Routing;
using Microsoft.Web.UnitTestUtil;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Html.Test
{
public class ValidationExtensionsTest
{
// Validate
[Fact]
public void Validate_AddsClientValidationMetadata()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext()
{
FormId = "form_id"
};
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
htmlHelper.Validate("baz");
// Assert
Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void Validate_DoesNothingIfClientValidationIsNotEnabled()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
htmlHelper.ViewContext.FormContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = false;
// Act
htmlHelper.Validate("foo");
// Assert
Assert.Empty(htmlHelper.ViewContext.FormContext.FieldValidators);
}
[Fact]
public void Validate_DoesNothingIfUnobtrusiveJavaScriptIsEnabled()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
htmlHelper.ViewContext.FormContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
// Act
htmlHelper.Validate("foo");
// Assert
Assert.Empty(htmlHelper.ViewContext.FormContext.FieldValidators);
}
[Fact]
public void Validate_ThrowsIfModelNameIsNull()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act & assert
Assert.ThrowsArgumentNull(
delegate { htmlHelper.Validate((string)null /* modelName */); }, "modelName");
}
[Fact]
public void ValidateFor_AddsClientValidationMetadata()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext()
{
FormId = "form_id"
};
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
htmlHelper.ValidateFor(m => m.baz);
// Assert
Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
// ValidationMessage
[Fact]
public void ValidationMessageAllowsEmptyModelName()
{
// Arrange
ViewDataDictionary vdd = new ViewDataDictionary();
vdd.ModelState.AddModelError("", "some error text");
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(vdd);
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("");
// Assert
Assert.Equal(@"<span class=""field-validation-error"">some error text</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsNullForNullModelState()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithNullModelState());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo");
// Assert
Assert.Null(html);
}
[Fact]
public void ValidationMessageReturnsFirstErrorWithMessage()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo");
// Assert
Assert.Equal(@"<span class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsGenericMessageInsteadOfExceptionText()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("quux");
// Assert
Assert.Equal(@"<span class=""field-validation-error"">The value &#39;quuxValue&#39; is invalid.</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsNullForInvalidName()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("boo");
// Assert
Assert.Null(html);
}
[Fact]
public void ValidationMessageReturnsWithObjectAttributes()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo", new { bar = "bar" });
// Assert
Assert.Equal(@"<span bar=""bar"" class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsWithObjectAttributesWithUnderscores()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo", new { foo_bar = "bar" });
// Assert
Assert.Equal(@"<span class=""field-validation-error"" foo-bar=""bar"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsWithCustomMessage()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo", "bar error");
// Assert
Assert.Equal(@"<span class=""field-validation-error"">bar error</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsWithCustomMessageAndObjectAttributes()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo", "bar error", new { baz = "baz" });
// Assert
Assert.Equal(@"<span baz=""baz"" class=""field-validation-error"">bar error</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageReturnsWithCustomMessageAndObjectAttributesWithUnderscores()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo", "bar error", new { foo_baz = "baz" });
// Assert
Assert.Equal(@"<span class=""field-validation-error"" foo-baz=""baz"">bar error</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageThrowsIfModelNameIsNull()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
// Act & Assert
Assert.ThrowsArgumentNull(
delegate { htmlHelper.ValidationMessage(null); }, "modelName");
}
[Fact]
public void ValidationMessageWithClientValidation_DefaultMessage_Valid()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("baz"); // 'baz' is valid
// Assert
Assert.Equal(@"<span class=""field-validation-valid"" id=""baz_validationMessage""></span>", html.ToHtmlString());
Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
Assert.Equal("baz_validationMessage", formContext.FieldValidators["baz"].ValidationMessageId);
Assert.True(formContext.FieldValidators["baz"].ReplaceValidationMessageContents);
Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void ValidationMessageWithClientValidation_DefaultMessage_Valid_Unobtrusive()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("baz"); // 'baz' is valid
// Assert
Assert.Equal(@"<span class=""field-validation-valid"" data-valmsg-for=""baz"" data-valmsg-replace=""true""></span>", html.ToHtmlString());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void ValidationMessageWithClientValidation_ExplicitMessage_Valid()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("baz", "some explicit message"); // 'baz' is valid
// Assert
Assert.Equal(@"<span class=""field-validation-valid"" id=""baz_validationMessage"">some explicit message</span>", html.ToHtmlString());
Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
Assert.Equal("baz_validationMessage", formContext.FieldValidators["baz"].ValidationMessageId);
Assert.False(formContext.FieldValidators["baz"].ReplaceValidationMessageContents);
Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void ValidationMessageWithClientValidation_ExplicitMessage_Valid_Unobtrusive()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("baz", "some explicit message"); // 'baz' is valid
// Assert
Assert.Equal(@"<span class=""field-validation-valid"" data-valmsg-for=""baz"" data-valmsg-replace=""false"">some explicit message</span>", html.ToHtmlString());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void ValidationMessageWithModelStateAndNoErrors()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("baz");
// Assert
Assert.Null(html);
}
// ValidationMessageFor
[Fact]
public void ValidationMessageForThrowsIfExpressionIsNull()
{
// Arrange
HtmlHelper<object> htmlHelper = MvcHelper.GetHtmlHelper();
// Act & Assert
Assert.ThrowsArgumentNull(
() => htmlHelper.ValidationMessageFor<object, object>(null),
"expression"
);
}
[Fact]
public void ValidationMessageForReturnsNullIfModelStateIsNull()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithNullModelState());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo);
// Assert
Assert.Null(html);
}
[Fact]
public void ValidationMessageForReturnsFirstErrorWithErrorMessage()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo);
// Assert
Assert.Equal(@"<span class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageForReturnsGenericMessageInsteadOfExceptionText()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.quux);
// Assert
Assert.Equal(@"<span class=""field-validation-error"">The value &#39;quuxValue&#39; is invalid.</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageForReturnsWithObjectAttributes()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, null /* validationMessage */, new { bar = "bar" });
// Assert
Assert.Equal(@"<span bar=""bar"" class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageForReturnsWithObjectAttributesWithUnderscores()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, null /* validationMessage */, new { foo_bar = "bar" });
// Assert
Assert.Equal(@"<span class=""field-validation-error"" foo-bar=""bar"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageForReturnsWithCustomMessage()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, "bar error");
// Assert
Assert.Equal(@"<span class=""field-validation-error"">bar error</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageForReturnsWithCustomMessageAndObjectAttributes()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, "bar error", new { baz = "baz" });
// Assert
Assert.Equal(@"<span baz=""baz"" class=""field-validation-error"">bar error</span>", html.ToHtmlString());
}
[Fact]
public void ValidationMessageForWithClientValidation()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.baz);
// Assert
Assert.Equal(@"<span class=""field-validation-valid"" id=""baz_validationMessage""></span>", html.ToHtmlString());
Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
Assert.Equal("baz_validationMessage", formContext.FieldValidators["baz"].ValidationMessageId);
Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void ValidationMessageForWithClientValidation_Unobtrusive()
{
var originalProviders = ModelValidatorProviders.Providers.ToArray();
ModelValidatorProviders.Providers.Clear();
try
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
FormContext formContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
htmlHelper.ViewContext.FormContext = formContext;
ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
{
new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
};
Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
mockValidator.Setup(v => v.GetClientValidationRules())
.Returns(expectedValidationRules);
Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
.Returns(new[] { mockValidator.Object });
ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.baz);
// Assert
Assert.Equal(@"<span class=""field-validation-valid"" data-valmsg-for=""baz"" data-valmsg-replace=""true""></span>", html.ToHtmlString());
}
finally
{
ModelValidatorProviders.Providers.Clear();
foreach (var provider in originalProviders)
{
ModelValidatorProviders.Providers.Add(provider);
}
}
}
[Fact]
public void ValidationMessageForWithModelStateAndNoErrors()
{
// Arrange
HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.baz);
// Assert
Assert.Null(html);
}
// ValidationSummary
[Fact]
public void ValidationSummary()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary();
// Assert
Assert.Equal(@"<div class=""validation-summary-errors""><ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryAddsIdIfClientValidationEnabled()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
htmlHelper.ViewContext.FormContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
// Act
MvcHtmlString html = htmlHelper.ValidationSummary();
// Assert
Assert.Equal(@"<div class=""validation-summary-errors"" id=""validationSummary""><ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
Assert.Equal("validationSummary", htmlHelper.ViewContext.FormContext.ValidationSummaryId);
}
[Fact]
public void ValidationSummaryDoesNotAddIdIfUnobtrusiveJavaScriptEnabled()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
htmlHelper.ViewContext.FormContext = new FormContext();
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
// Act
MvcHtmlString html = htmlHelper.ValidationSummary();
// Assert
Assert.Equal(@"<div class=""validation-summary-errors"" data-valmsg-summary=""true""><ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>", html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithDictionary()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
RouteValueDictionary htmlAttributes = new RouteValueDictionary();
htmlAttributes["class"] = "my-class";
// Act
MvcHtmlString html = htmlHelper.ValidationSummary(null /* message */, htmlAttributes);
// Assert
Assert.Equal(@"<div class=""validation-summary-errors my-class""><ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithDictionaryAndMessage()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
RouteValueDictionary htmlAttributes = new RouteValueDictionary();
htmlAttributes["class"] = "my-class";
// Act
MvcHtmlString html = htmlHelper.ValidationSummary("This is my message.", htmlAttributes);
// Assert
Assert.Equal(@"<div class=""validation-summary-errors my-class""><span>This is my message.</span>
<ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithNoErrors_ReturnsNullIfClientValidationDisabled()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary();
// Assert
Assert.Null(html);
}
[Fact]
public void ValidationSummaryWithNoErrors_EmptyUlIfClientValidationEnabled()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary());
htmlHelper.ViewContext.ClientValidationEnabled = true;
htmlHelper.ViewContext.FormContext = new FormContext();
// Act
MvcHtmlString html = htmlHelper.ValidationSummary();
// Assert
Assert.Equal(@"<div class=""validation-summary-valid"" id=""validationSummary""><ul><li style=""display:none""></li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithObjectAttributes()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary(null /* message */, new { baz = "baz" });
// Assert
Assert.Equal(@"<div baz=""baz"" class=""validation-summary-errors""><ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithObjectAttributesWithUnderscores()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary(null /* message */, new { foo_baz = "baz" });
// Assert
Assert.Equal(@"<div class=""validation-summary-errors"" foo-baz=""baz""><ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithObjectAttributesAndMessage()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary("This is my message.", new { baz = "baz" });
// Assert
Assert.Equal(@"<div baz=""baz"" class=""validation-summary-errors""><span>This is my message.</span>
<ul><li>foo error &lt;1&gt;</li>
<li>foo error 2</li>
<li>bar error &lt;1&gt;</li>
<li>bar error 2</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithNoModelErrors()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary(true /* excludePropertyErrors */, "This is my message.");
// Assert
Assert.Equal(@"<div class=""validation-summary-errors""><span>This is my message.</span>
<ul><li style=""display:none""></li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithOnlyModelErrors()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelAndPropertyErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary(true /* excludePropertyErrors */, "This is my message.");
// Assert
Assert.Equal(@"<div class=""validation-summary-errors""><span>This is my message.</span>
<ul><li>Something is wrong.</li>
<li>Something else is also wrong.</li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationSummaryWithOnlyModelErrorsAndPrefix()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors("MyPrefix"));
// Act
MvcHtmlString html = htmlHelper.ValidationSummary(true /* excludePropertyErrors */, "This is my message.");
// Assert
Assert.Equal(@"<div class=""validation-summary-errors""><span>This is my message.</span>
<ul><li style=""display:none""></li>
</ul></div>"
, html.ToHtmlString());
}
[Fact]
public void ValidationMessageWithPrefix()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors("MyPrefix"));
// Act
MvcHtmlString html = htmlHelper.ValidationMessage("foo");
// Assert
Assert.Equal(@"<span class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
}
[Fact]
public void ValidationErrorOrdering()
{
// Arrange
HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelWithDisplayOrderErrors());
// Act
MvcHtmlString html = htmlHelper.ValidationSummary();
// Assert
Assert.Equal(@"<div class=""validation-summary-errors""><ul><li>Error 1</li>
<li>Error 2</li>
<li>Error 3</li>
<li>Error 4</li>
</ul></div>", html.ToHtmlString());
}
private class ValidationModel
{
public string foo { get; set; }
public string bar { get; set; }
public string baz { get; set; }
public string quux { get; set; }
}
public class ModelWithOrdering
{
[Required]
[Display(Order = 2)]
public int Second { get; set; }
[Required]
[Display(Order = 1)]
public string First { get; set; }
[Required]
[Display(Order = 4)]
public string Fourth { get; set; }
[Required]
[Display(Order = 3)]
public string Third { get; set; }
}
private static ViewDataDictionary<ValidationModel> GetViewDataWithNullModelState()
{
ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
viewData.ModelState["foo"] = null;
return viewData;
}
private static ViewDataDictionary<ValidationModel> GetViewDataWithModelErrors()
{
ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
ModelState modelStateFoo = new ModelState();
ModelState modelStateBar = new ModelState();
ModelState modelStateBaz = new ModelState();
modelStateFoo.Errors.Add(new ModelError(new InvalidOperationException("foo error from exception")));
modelStateFoo.Errors.Add(new ModelError("foo error <1>"));
modelStateFoo.Errors.Add(new ModelError("foo error 2"));
modelStateBar.Errors.Add(new ModelError("bar error <1>"));
modelStateBar.Errors.Add(new ModelError("bar error 2"));
viewData.ModelState["foo"] = modelStateFoo;
viewData.ModelState["bar"] = modelStateBar;
viewData.ModelState["baz"] = modelStateBaz;
viewData.ModelState.SetModelValue("quux", new ValueProviderResult(null, "quuxValue", null));
viewData.ModelState.AddModelError("quux", new InvalidOperationException("Some error text."));
return viewData;
}
private static ViewDataDictionary<ValidationModel> GetViewDataWithModelAndPropertyErrors()
{
ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
ModelState modelStateFoo = new ModelState();
ModelState modelStateBar = new ModelState();
ModelState modelStateBaz = new ModelState();
modelStateFoo.Errors.Add(new ModelError("foo error <1>"));
modelStateFoo.Errors.Add(new ModelError("foo error 2"));
modelStateBar.Errors.Add(new ModelError("bar error <1>"));
modelStateBar.Errors.Add(new ModelError("bar error 2"));
viewData.ModelState["foo"] = modelStateFoo;
viewData.ModelState["bar"] = modelStateBar;
viewData.ModelState["baz"] = modelStateBaz;
viewData.ModelState.SetModelValue("quux", new ValueProviderResult(null, "quuxValue", null));
viewData.ModelState.AddModelError("quux", new InvalidOperationException("Some error text."));
viewData.ModelState.AddModelError(String.Empty, "Something is wrong.");
viewData.ModelState.AddModelError(String.Empty, "Something else is also wrong.");
return viewData;
}
private static ViewDataDictionary<ValidationModel> GetViewDataWithModelErrors(string prefix)
{
ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
viewData.TemplateInfo.HtmlFieldPrefix = prefix;
ModelState modelStateFoo = new ModelState();
ModelState modelStateBar = new ModelState();
ModelState modelStateBaz = new ModelState();
modelStateFoo.Errors.Add(new ModelError("foo error <1>"));
modelStateFoo.Errors.Add(new ModelError("foo error 2"));
modelStateBar.Errors.Add(new ModelError("bar error <1>"));
modelStateBar.Errors.Add(new ModelError("bar error 2"));
viewData.ModelState[prefix + ".foo"] = modelStateFoo;
viewData.ModelState[prefix + ".bar"] = modelStateBar;
viewData.ModelState[prefix + ".baz"] = modelStateBaz;
viewData.ModelState.SetModelValue(prefix + ".quux", new ValueProviderResult(null, "quuxValue", null));
viewData.ModelState.AddModelError(prefix + ".quux", new InvalidOperationException("Some error text."));
return viewData;
}
private static ViewDataDictionary<ModelWithOrdering> GetViewDataWithModelWithDisplayOrderErrors()
{
ViewDataDictionary<ModelWithOrdering> viewData = new ViewDataDictionary<ModelWithOrdering>();
var model = new ModelWithOrdering();
// Error names for each property on ModelWithOrdering.
viewData.ModelState.AddModelError("First", "Error 1");
viewData.ModelState.AddModelError("Second", "Error 2");
viewData.ModelState.AddModelError("Third", "Error 3");
viewData.ModelState.AddModelError("Fourth", "Error 4");
return viewData;
}
}
}