PageRenderTime 30ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/test/System.Web.Mvc.Test/Html/Test/ValidationExtensionsTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 1086 lines | 759 code | 184 blank | 143 comment | 0 complexity | e3f3b0313d86667be1b981f26ac7fcfb MD5 | raw file
  1. using System.ComponentModel.DataAnnotations;
  2. using System.Linq;
  3. using System.Web.Routing;
  4. using Microsoft.Web.UnitTestUtil;
  5. using Moq;
  6. using Xunit;
  7. using Assert = Microsoft.TestCommon.AssertEx;
  8. namespace System.Web.Mvc.Html.Test
  9. {
  10. public class ValidationExtensionsTest
  11. {
  12. // Validate
  13. [Fact]
  14. public void Validate_AddsClientValidationMetadata()
  15. {
  16. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  17. ModelValidatorProviders.Providers.Clear();
  18. try
  19. {
  20. // Arrange
  21. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  22. FormContext formContext = new FormContext()
  23. {
  24. FormId = "form_id"
  25. };
  26. htmlHelper.ViewContext.ClientValidationEnabled = true;
  27. htmlHelper.ViewContext.FormContext = formContext;
  28. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  29. {
  30. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  31. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  32. };
  33. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  34. mockValidator.Setup(v => v.GetClientValidationRules())
  35. .Returns(expectedValidationRules);
  36. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  37. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  38. .Returns(new[] { mockValidator.Object });
  39. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  40. // Act
  41. htmlHelper.Validate("baz");
  42. // Assert
  43. Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
  44. Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
  45. }
  46. finally
  47. {
  48. ModelValidatorProviders.Providers.Clear();
  49. foreach (var provider in originalProviders)
  50. {
  51. ModelValidatorProviders.Providers.Add(provider);
  52. }
  53. }
  54. }
  55. [Fact]
  56. public void Validate_DoesNothingIfClientValidationIsNotEnabled()
  57. {
  58. // Arrange
  59. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  60. htmlHelper.ViewContext.FormContext = new FormContext();
  61. htmlHelper.ViewContext.ClientValidationEnabled = false;
  62. // Act
  63. htmlHelper.Validate("foo");
  64. // Assert
  65. Assert.Empty(htmlHelper.ViewContext.FormContext.FieldValidators);
  66. }
  67. [Fact]
  68. public void Validate_DoesNothingIfUnobtrusiveJavaScriptIsEnabled()
  69. {
  70. // Arrange
  71. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  72. htmlHelper.ViewContext.FormContext = new FormContext();
  73. htmlHelper.ViewContext.ClientValidationEnabled = true;
  74. htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
  75. // Act
  76. htmlHelper.Validate("foo");
  77. // Assert
  78. Assert.Empty(htmlHelper.ViewContext.FormContext.FieldValidators);
  79. }
  80. [Fact]
  81. public void Validate_ThrowsIfModelNameIsNull()
  82. {
  83. // Arrange
  84. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  85. // Act & assert
  86. Assert.ThrowsArgumentNull(
  87. delegate { htmlHelper.Validate((string)null /* modelName */); }, "modelName");
  88. }
  89. [Fact]
  90. public void ValidateFor_AddsClientValidationMetadata()
  91. {
  92. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  93. ModelValidatorProviders.Providers.Clear();
  94. try
  95. {
  96. // Arrange
  97. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  98. FormContext formContext = new FormContext()
  99. {
  100. FormId = "form_id"
  101. };
  102. htmlHelper.ViewContext.ClientValidationEnabled = true;
  103. htmlHelper.ViewContext.FormContext = formContext;
  104. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  105. {
  106. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  107. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  108. };
  109. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  110. mockValidator.Setup(v => v.GetClientValidationRules())
  111. .Returns(expectedValidationRules);
  112. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  113. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  114. .Returns(new[] { mockValidator.Object });
  115. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  116. // Act
  117. htmlHelper.ValidateFor(m => m.baz);
  118. // Assert
  119. Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
  120. Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
  121. }
  122. finally
  123. {
  124. ModelValidatorProviders.Providers.Clear();
  125. foreach (var provider in originalProviders)
  126. {
  127. ModelValidatorProviders.Providers.Add(provider);
  128. }
  129. }
  130. }
  131. // ValidationMessage
  132. [Fact]
  133. public void ValidationMessageAllowsEmptyModelName()
  134. {
  135. // Arrange
  136. ViewDataDictionary vdd = new ViewDataDictionary();
  137. vdd.ModelState.AddModelError("", "some error text");
  138. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(vdd);
  139. // Act
  140. MvcHtmlString html = htmlHelper.ValidationMessage("");
  141. // Assert
  142. Assert.Equal(@"<span class=""field-validation-error"">some error text</span>", html.ToHtmlString());
  143. }
  144. [Fact]
  145. public void ValidationMessageReturnsNullForNullModelState()
  146. {
  147. // Arrange
  148. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithNullModelState());
  149. // Act
  150. MvcHtmlString html = htmlHelper.ValidationMessage("foo");
  151. // Assert
  152. Assert.Null(html);
  153. }
  154. [Fact]
  155. public void ValidationMessageReturnsFirstErrorWithMessage()
  156. {
  157. // Arrange
  158. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  159. // Act
  160. MvcHtmlString html = htmlHelper.ValidationMessage("foo");
  161. // Assert
  162. Assert.Equal(@"<span class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  163. }
  164. [Fact]
  165. public void ValidationMessageReturnsGenericMessageInsteadOfExceptionText()
  166. {
  167. // Arrange
  168. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  169. // Act
  170. MvcHtmlString html = htmlHelper.ValidationMessage("quux");
  171. // Assert
  172. Assert.Equal(@"<span class=""field-validation-error"">The value &#39;quuxValue&#39; is invalid.</span>", html.ToHtmlString());
  173. }
  174. [Fact]
  175. public void ValidationMessageReturnsNullForInvalidName()
  176. {
  177. // Arrange
  178. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  179. // Act
  180. MvcHtmlString html = htmlHelper.ValidationMessage("boo");
  181. // Assert
  182. Assert.Null(html);
  183. }
  184. [Fact]
  185. public void ValidationMessageReturnsWithObjectAttributes()
  186. {
  187. // Arrange
  188. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  189. // Act
  190. MvcHtmlString html = htmlHelper.ValidationMessage("foo", new { bar = "bar" });
  191. // Assert
  192. Assert.Equal(@"<span bar=""bar"" class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  193. }
  194. [Fact]
  195. public void ValidationMessageReturnsWithObjectAttributesWithUnderscores()
  196. {
  197. // Arrange
  198. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  199. // Act
  200. MvcHtmlString html = htmlHelper.ValidationMessage("foo", new { foo_bar = "bar" });
  201. // Assert
  202. Assert.Equal(@"<span class=""field-validation-error"" foo-bar=""bar"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  203. }
  204. [Fact]
  205. public void ValidationMessageReturnsWithCustomMessage()
  206. {
  207. // Arrange
  208. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  209. // Act
  210. MvcHtmlString html = htmlHelper.ValidationMessage("foo", "bar error");
  211. // Assert
  212. Assert.Equal(@"<span class=""field-validation-error"">bar error</span>", html.ToHtmlString());
  213. }
  214. [Fact]
  215. public void ValidationMessageReturnsWithCustomMessageAndObjectAttributes()
  216. {
  217. // Arrange
  218. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  219. // Act
  220. MvcHtmlString html = htmlHelper.ValidationMessage("foo", "bar error", new { baz = "baz" });
  221. // Assert
  222. Assert.Equal(@"<span baz=""baz"" class=""field-validation-error"">bar error</span>", html.ToHtmlString());
  223. }
  224. [Fact]
  225. public void ValidationMessageReturnsWithCustomMessageAndObjectAttributesWithUnderscores()
  226. {
  227. // Arrange
  228. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  229. // Act
  230. MvcHtmlString html = htmlHelper.ValidationMessage("foo", "bar error", new { foo_baz = "baz" });
  231. // Assert
  232. Assert.Equal(@"<span class=""field-validation-error"" foo-baz=""baz"">bar error</span>", html.ToHtmlString());
  233. }
  234. [Fact]
  235. public void ValidationMessageThrowsIfModelNameIsNull()
  236. {
  237. // Arrange
  238. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  239. // Act & Assert
  240. Assert.ThrowsArgumentNull(
  241. delegate { htmlHelper.ValidationMessage(null); }, "modelName");
  242. }
  243. [Fact]
  244. public void ValidationMessageWithClientValidation_DefaultMessage_Valid()
  245. {
  246. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  247. ModelValidatorProviders.Providers.Clear();
  248. try
  249. {
  250. // Arrange
  251. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  252. FormContext formContext = new FormContext();
  253. htmlHelper.ViewContext.ClientValidationEnabled = true;
  254. htmlHelper.ViewContext.FormContext = formContext;
  255. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  256. {
  257. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  258. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  259. };
  260. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  261. mockValidator.Setup(v => v.GetClientValidationRules())
  262. .Returns(expectedValidationRules);
  263. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  264. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  265. .Returns(new[] { mockValidator.Object });
  266. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  267. // Act
  268. MvcHtmlString html = htmlHelper.ValidationMessage("baz"); // 'baz' is valid
  269. // Assert
  270. Assert.Equal(@"<span class=""field-validation-valid"" id=""baz_validationMessage""></span>", html.ToHtmlString());
  271. Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
  272. Assert.Equal("baz_validationMessage", formContext.FieldValidators["baz"].ValidationMessageId);
  273. Assert.True(formContext.FieldValidators["baz"].ReplaceValidationMessageContents);
  274. Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
  275. }
  276. finally
  277. {
  278. ModelValidatorProviders.Providers.Clear();
  279. foreach (var provider in originalProviders)
  280. {
  281. ModelValidatorProviders.Providers.Add(provider);
  282. }
  283. }
  284. }
  285. [Fact]
  286. public void ValidationMessageWithClientValidation_DefaultMessage_Valid_Unobtrusive()
  287. {
  288. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  289. ModelValidatorProviders.Providers.Clear();
  290. try
  291. {
  292. // Arrange
  293. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  294. FormContext formContext = new FormContext();
  295. htmlHelper.ViewContext.ClientValidationEnabled = true;
  296. htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
  297. htmlHelper.ViewContext.FormContext = formContext;
  298. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  299. {
  300. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  301. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  302. };
  303. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  304. mockValidator.Setup(v => v.GetClientValidationRules())
  305. .Returns(expectedValidationRules);
  306. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  307. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  308. .Returns(new[] { mockValidator.Object });
  309. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  310. // Act
  311. MvcHtmlString html = htmlHelper.ValidationMessage("baz"); // 'baz' is valid
  312. // Assert
  313. Assert.Equal(@"<span class=""field-validation-valid"" data-valmsg-for=""baz"" data-valmsg-replace=""true""></span>", html.ToHtmlString());
  314. }
  315. finally
  316. {
  317. ModelValidatorProviders.Providers.Clear();
  318. foreach (var provider in originalProviders)
  319. {
  320. ModelValidatorProviders.Providers.Add(provider);
  321. }
  322. }
  323. }
  324. [Fact]
  325. public void ValidationMessageWithClientValidation_ExplicitMessage_Valid()
  326. {
  327. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  328. ModelValidatorProviders.Providers.Clear();
  329. try
  330. {
  331. // Arrange
  332. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  333. FormContext formContext = new FormContext();
  334. htmlHelper.ViewContext.ClientValidationEnabled = true;
  335. htmlHelper.ViewContext.FormContext = formContext;
  336. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  337. {
  338. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  339. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  340. };
  341. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  342. mockValidator.Setup(v => v.GetClientValidationRules())
  343. .Returns(expectedValidationRules);
  344. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  345. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  346. .Returns(new[] { mockValidator.Object });
  347. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  348. // Act
  349. MvcHtmlString html = htmlHelper.ValidationMessage("baz", "some explicit message"); // 'baz' is valid
  350. // Assert
  351. Assert.Equal(@"<span class=""field-validation-valid"" id=""baz_validationMessage"">some explicit message</span>", html.ToHtmlString());
  352. Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
  353. Assert.Equal("baz_validationMessage", formContext.FieldValidators["baz"].ValidationMessageId);
  354. Assert.False(formContext.FieldValidators["baz"].ReplaceValidationMessageContents);
  355. Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
  356. }
  357. finally
  358. {
  359. ModelValidatorProviders.Providers.Clear();
  360. foreach (var provider in originalProviders)
  361. {
  362. ModelValidatorProviders.Providers.Add(provider);
  363. }
  364. }
  365. }
  366. [Fact]
  367. public void ValidationMessageWithClientValidation_ExplicitMessage_Valid_Unobtrusive()
  368. {
  369. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  370. ModelValidatorProviders.Providers.Clear();
  371. try
  372. {
  373. // Arrange
  374. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  375. FormContext formContext = new FormContext();
  376. htmlHelper.ViewContext.ClientValidationEnabled = true;
  377. htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
  378. htmlHelper.ViewContext.FormContext = formContext;
  379. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  380. {
  381. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  382. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  383. };
  384. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  385. mockValidator.Setup(v => v.GetClientValidationRules())
  386. .Returns(expectedValidationRules);
  387. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  388. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  389. .Returns(new[] { mockValidator.Object });
  390. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  391. // Act
  392. MvcHtmlString html = htmlHelper.ValidationMessage("baz", "some explicit message"); // 'baz' is valid
  393. // Assert
  394. Assert.Equal(@"<span class=""field-validation-valid"" data-valmsg-for=""baz"" data-valmsg-replace=""false"">some explicit message</span>", html.ToHtmlString());
  395. }
  396. finally
  397. {
  398. ModelValidatorProviders.Providers.Clear();
  399. foreach (var provider in originalProviders)
  400. {
  401. ModelValidatorProviders.Providers.Add(provider);
  402. }
  403. }
  404. }
  405. [Fact]
  406. public void ValidationMessageWithModelStateAndNoErrors()
  407. {
  408. // Arrange
  409. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  410. // Act
  411. MvcHtmlString html = htmlHelper.ValidationMessage("baz");
  412. // Assert
  413. Assert.Null(html);
  414. }
  415. // ValidationMessageFor
  416. [Fact]
  417. public void ValidationMessageForThrowsIfExpressionIsNull()
  418. {
  419. // Arrange
  420. HtmlHelper<object> htmlHelper = MvcHelper.GetHtmlHelper();
  421. // Act & Assert
  422. Assert.ThrowsArgumentNull(
  423. () => htmlHelper.ValidationMessageFor<object, object>(null),
  424. "expression"
  425. );
  426. }
  427. [Fact]
  428. public void ValidationMessageForReturnsNullIfModelStateIsNull()
  429. {
  430. // Arrange
  431. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithNullModelState());
  432. // Act
  433. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo);
  434. // Assert
  435. Assert.Null(html);
  436. }
  437. [Fact]
  438. public void ValidationMessageForReturnsFirstErrorWithErrorMessage()
  439. {
  440. // Arrange
  441. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  442. // Act
  443. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo);
  444. // Assert
  445. Assert.Equal(@"<span class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  446. }
  447. [Fact]
  448. public void ValidationMessageForReturnsGenericMessageInsteadOfExceptionText()
  449. {
  450. // Arrange
  451. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  452. // Act
  453. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.quux);
  454. // Assert
  455. Assert.Equal(@"<span class=""field-validation-error"">The value &#39;quuxValue&#39; is invalid.</span>", html.ToHtmlString());
  456. }
  457. [Fact]
  458. public void ValidationMessageForReturnsWithObjectAttributes()
  459. {
  460. // Arrange
  461. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  462. // Act
  463. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, null /* validationMessage */, new { bar = "bar" });
  464. // Assert
  465. Assert.Equal(@"<span bar=""bar"" class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  466. }
  467. [Fact]
  468. public void ValidationMessageForReturnsWithObjectAttributesWithUnderscores()
  469. {
  470. // Arrange
  471. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  472. // Act
  473. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, null /* validationMessage */, new { foo_bar = "bar" });
  474. // Assert
  475. Assert.Equal(@"<span class=""field-validation-error"" foo-bar=""bar"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  476. }
  477. [Fact]
  478. public void ValidationMessageForReturnsWithCustomMessage()
  479. {
  480. // Arrange
  481. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  482. // Act
  483. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, "bar error");
  484. // Assert
  485. Assert.Equal(@"<span class=""field-validation-error"">bar error</span>", html.ToHtmlString());
  486. }
  487. [Fact]
  488. public void ValidationMessageForReturnsWithCustomMessageAndObjectAttributes()
  489. {
  490. // Arrange
  491. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  492. // Act
  493. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.foo, "bar error", new { baz = "baz" });
  494. // Assert
  495. Assert.Equal(@"<span baz=""baz"" class=""field-validation-error"">bar error</span>", html.ToHtmlString());
  496. }
  497. [Fact]
  498. public void ValidationMessageForWithClientValidation()
  499. {
  500. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  501. ModelValidatorProviders.Providers.Clear();
  502. try
  503. {
  504. // Arrange
  505. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  506. FormContext formContext = new FormContext();
  507. htmlHelper.ViewContext.ClientValidationEnabled = true;
  508. htmlHelper.ViewContext.FormContext = formContext;
  509. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  510. {
  511. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  512. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  513. };
  514. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  515. mockValidator.Setup(v => v.GetClientValidationRules())
  516. .Returns(expectedValidationRules);
  517. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  518. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  519. .Returns(new[] { mockValidator.Object });
  520. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  521. // Act
  522. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.baz);
  523. // Assert
  524. Assert.Equal(@"<span class=""field-validation-valid"" id=""baz_validationMessage""></span>", html.ToHtmlString());
  525. Assert.NotNull(formContext.GetValidationMetadataForField("baz"));
  526. Assert.Equal("baz_validationMessage", formContext.FieldValidators["baz"].ValidationMessageId);
  527. Assert.Equal(expectedValidationRules, formContext.FieldValidators["baz"].ValidationRules.ToArray());
  528. }
  529. finally
  530. {
  531. ModelValidatorProviders.Providers.Clear();
  532. foreach (var provider in originalProviders)
  533. {
  534. ModelValidatorProviders.Providers.Add(provider);
  535. }
  536. }
  537. }
  538. [Fact]
  539. public void ValidationMessageForWithClientValidation_Unobtrusive()
  540. {
  541. var originalProviders = ModelValidatorProviders.Providers.ToArray();
  542. ModelValidatorProviders.Providers.Clear();
  543. try
  544. {
  545. // Arrange
  546. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  547. FormContext formContext = new FormContext();
  548. htmlHelper.ViewContext.ClientValidationEnabled = true;
  549. htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
  550. htmlHelper.ViewContext.FormContext = formContext;
  551. ModelClientValidationRule[] expectedValidationRules = new ModelClientValidationRule[]
  552. {
  553. new ModelClientValidationRule() { ValidationType = "ValidationRule1" },
  554. new ModelClientValidationRule() { ValidationType = "ValidationRule2" }
  555. };
  556. Mock<ModelValidator> mockValidator = new Mock<ModelValidator>(ModelMetadata.FromStringExpression("", htmlHelper.ViewContext.ViewData), htmlHelper.ViewContext);
  557. mockValidator.Setup(v => v.GetClientValidationRules())
  558. .Returns(expectedValidationRules);
  559. Mock<ModelValidatorProvider> mockValidatorProvider = new Mock<ModelValidatorProvider>();
  560. mockValidatorProvider.Setup(vp => vp.GetValidators(It.IsAny<ModelMetadata>(), It.IsAny<ControllerContext>()))
  561. .Returns(new[] { mockValidator.Object });
  562. ModelValidatorProviders.Providers.Add(mockValidatorProvider.Object);
  563. // Act
  564. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.baz);
  565. // Assert
  566. Assert.Equal(@"<span class=""field-validation-valid"" data-valmsg-for=""baz"" data-valmsg-replace=""true""></span>", html.ToHtmlString());
  567. }
  568. finally
  569. {
  570. ModelValidatorProviders.Providers.Clear();
  571. foreach (var provider in originalProviders)
  572. {
  573. ModelValidatorProviders.Providers.Add(provider);
  574. }
  575. }
  576. }
  577. [Fact]
  578. public void ValidationMessageForWithModelStateAndNoErrors()
  579. {
  580. // Arrange
  581. HtmlHelper<ValidationModel> htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  582. // Act
  583. MvcHtmlString html = htmlHelper.ValidationMessageFor(m => m.baz);
  584. // Assert
  585. Assert.Null(html);
  586. }
  587. // ValidationSummary
  588. [Fact]
  589. public void ValidationSummary()
  590. {
  591. // Arrange
  592. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  593. // Act
  594. MvcHtmlString html = htmlHelper.ValidationSummary();
  595. // Assert
  596. Assert.Equal(@"<div class=""validation-summary-errors""><ul><li>foo error &lt;1&gt;</li>
  597. <li>foo error 2</li>
  598. <li>bar error &lt;1&gt;</li>
  599. <li>bar error 2</li>
  600. </ul></div>"
  601. , html.ToHtmlString());
  602. }
  603. [Fact]
  604. public void ValidationSummaryAddsIdIfClientValidationEnabled()
  605. {
  606. // Arrange
  607. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  608. htmlHelper.ViewContext.FormContext = new FormContext();
  609. htmlHelper.ViewContext.ClientValidationEnabled = true;
  610. // Act
  611. MvcHtmlString html = htmlHelper.ValidationSummary();
  612. // Assert
  613. Assert.Equal(@"<div class=""validation-summary-errors"" id=""validationSummary""><ul><li>foo error &lt;1&gt;</li>
  614. <li>foo error 2</li>
  615. <li>bar error &lt;1&gt;</li>
  616. <li>bar error 2</li>
  617. </ul></div>"
  618. , html.ToHtmlString());
  619. Assert.Equal("validationSummary", htmlHelper.ViewContext.FormContext.ValidationSummaryId);
  620. }
  621. [Fact]
  622. public void ValidationSummaryDoesNotAddIdIfUnobtrusiveJavaScriptEnabled()
  623. {
  624. // Arrange
  625. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  626. htmlHelper.ViewContext.FormContext = new FormContext();
  627. htmlHelper.ViewContext.ClientValidationEnabled = true;
  628. htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled = true;
  629. // Act
  630. MvcHtmlString html = htmlHelper.ValidationSummary();
  631. // Assert
  632. Assert.Equal(@"<div class=""validation-summary-errors"" data-valmsg-summary=""true""><ul><li>foo error &lt;1&gt;</li>
  633. <li>foo error 2</li>
  634. <li>bar error &lt;1&gt;</li>
  635. <li>bar error 2</li>
  636. </ul></div>", html.ToHtmlString());
  637. }
  638. [Fact]
  639. public void ValidationSummaryWithDictionary()
  640. {
  641. // Arrange
  642. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  643. RouteValueDictionary htmlAttributes = new RouteValueDictionary();
  644. htmlAttributes["class"] = "my-class";
  645. // Act
  646. MvcHtmlString html = htmlHelper.ValidationSummary(null /* message */, htmlAttributes);
  647. // Assert
  648. Assert.Equal(@"<div class=""validation-summary-errors my-class""><ul><li>foo error &lt;1&gt;</li>
  649. <li>foo error 2</li>
  650. <li>bar error &lt;1&gt;</li>
  651. <li>bar error 2</li>
  652. </ul></div>"
  653. , html.ToHtmlString());
  654. }
  655. [Fact]
  656. public void ValidationSummaryWithDictionaryAndMessage()
  657. {
  658. // Arrange
  659. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  660. RouteValueDictionary htmlAttributes = new RouteValueDictionary();
  661. htmlAttributes["class"] = "my-class";
  662. // Act
  663. MvcHtmlString html = htmlHelper.ValidationSummary("This is my message.", htmlAttributes);
  664. // Assert
  665. Assert.Equal(@"<div class=""validation-summary-errors my-class""><span>This is my message.</span>
  666. <ul><li>foo error &lt;1&gt;</li>
  667. <li>foo error 2</li>
  668. <li>bar error &lt;1&gt;</li>
  669. <li>bar error 2</li>
  670. </ul></div>"
  671. , html.ToHtmlString());
  672. }
  673. [Fact]
  674. public void ValidationSummaryWithNoErrors_ReturnsNullIfClientValidationDisabled()
  675. {
  676. // Arrange
  677. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary());
  678. // Act
  679. MvcHtmlString html = htmlHelper.ValidationSummary();
  680. // Assert
  681. Assert.Null(html);
  682. }
  683. [Fact]
  684. public void ValidationSummaryWithNoErrors_EmptyUlIfClientValidationEnabled()
  685. {
  686. // Arrange
  687. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary());
  688. htmlHelper.ViewContext.ClientValidationEnabled = true;
  689. htmlHelper.ViewContext.FormContext = new FormContext();
  690. // Act
  691. MvcHtmlString html = htmlHelper.ValidationSummary();
  692. // Assert
  693. Assert.Equal(@"<div class=""validation-summary-valid"" id=""validationSummary""><ul><li style=""display:none""></li>
  694. </ul></div>"
  695. , html.ToHtmlString());
  696. }
  697. [Fact]
  698. public void ValidationSummaryWithObjectAttributes()
  699. {
  700. // Arrange
  701. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  702. // Act
  703. MvcHtmlString html = htmlHelper.ValidationSummary(null /* message */, new { baz = "baz" });
  704. // Assert
  705. Assert.Equal(@"<div baz=""baz"" class=""validation-summary-errors""><ul><li>foo error &lt;1&gt;</li>
  706. <li>foo error 2</li>
  707. <li>bar error &lt;1&gt;</li>
  708. <li>bar error 2</li>
  709. </ul></div>"
  710. , html.ToHtmlString());
  711. }
  712. [Fact]
  713. public void ValidationSummaryWithObjectAttributesWithUnderscores()
  714. {
  715. // Arrange
  716. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  717. // Act
  718. MvcHtmlString html = htmlHelper.ValidationSummary(null /* message */, new { foo_baz = "baz" });
  719. // Assert
  720. Assert.Equal(@"<div class=""validation-summary-errors"" foo-baz=""baz""><ul><li>foo error &lt;1&gt;</li>
  721. <li>foo error 2</li>
  722. <li>bar error &lt;1&gt;</li>
  723. <li>bar error 2</li>
  724. </ul></div>"
  725. , html.ToHtmlString());
  726. }
  727. [Fact]
  728. public void ValidationSummaryWithObjectAttributesAndMessage()
  729. {
  730. // Arrange
  731. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  732. // Act
  733. MvcHtmlString html = htmlHelper.ValidationSummary("This is my message.", new { baz = "baz" });
  734. // Assert
  735. Assert.Equal(@"<div baz=""baz"" class=""validation-summary-errors""><span>This is my message.</span>
  736. <ul><li>foo error &lt;1&gt;</li>
  737. <li>foo error 2</li>
  738. <li>bar error &lt;1&gt;</li>
  739. <li>bar error 2</li>
  740. </ul></div>"
  741. , html.ToHtmlString());
  742. }
  743. [Fact]
  744. public void ValidationSummaryWithNoModelErrors()
  745. {
  746. // Arrange
  747. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors());
  748. // Act
  749. MvcHtmlString html = htmlHelper.ValidationSummary(true /* excludePropertyErrors */, "This is my message.");
  750. // Assert
  751. Assert.Equal(@"<div class=""validation-summary-errors""><span>This is my message.</span>
  752. <ul><li style=""display:none""></li>
  753. </ul></div>"
  754. , html.ToHtmlString());
  755. }
  756. [Fact]
  757. public void ValidationSummaryWithOnlyModelErrors()
  758. {
  759. // Arrange
  760. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelAndPropertyErrors());
  761. // Act
  762. MvcHtmlString html = htmlHelper.ValidationSummary(true /* excludePropertyErrors */, "This is my message.");
  763. // Assert
  764. Assert.Equal(@"<div class=""validation-summary-errors""><span>This is my message.</span>
  765. <ul><li>Something is wrong.</li>
  766. <li>Something else is also wrong.</li>
  767. </ul></div>"
  768. , html.ToHtmlString());
  769. }
  770. [Fact]
  771. public void ValidationSummaryWithOnlyModelErrorsAndPrefix()
  772. {
  773. // Arrange
  774. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors("MyPrefix"));
  775. // Act
  776. MvcHtmlString html = htmlHelper.ValidationSummary(true /* excludePropertyErrors */, "This is my message.");
  777. // Assert
  778. Assert.Equal(@"<div class=""validation-summary-errors""><span>This is my message.</span>
  779. <ul><li style=""display:none""></li>
  780. </ul></div>"
  781. , html.ToHtmlString());
  782. }
  783. [Fact]
  784. public void ValidationMessageWithPrefix()
  785. {
  786. // Arrange
  787. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelErrors("MyPrefix"));
  788. // Act
  789. MvcHtmlString html = htmlHelper.ValidationMessage("foo");
  790. // Assert
  791. Assert.Equal(@"<span class=""field-validation-error"">foo error &lt;1&gt;</span>", html.ToHtmlString());
  792. }
  793. [Fact]
  794. public void ValidationErrorOrdering()
  795. {
  796. // Arrange
  797. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(GetViewDataWithModelWithDisplayOrderErrors());
  798. // Act
  799. MvcHtmlString html = htmlHelper.ValidationSummary();
  800. // Assert
  801. Assert.Equal(@"<div class=""validation-summary-errors""><ul><li>Error 1</li>
  802. <li>Error 2</li>
  803. <li>Error 3</li>
  804. <li>Error 4</li>
  805. </ul></div>", html.ToHtmlString());
  806. }
  807. private class ValidationModel
  808. {
  809. public string foo { get; set; }
  810. public string bar { get; set; }
  811. public string baz { get; set; }
  812. public string quux { get; set; }
  813. }
  814. public class ModelWithOrdering
  815. {
  816. [Required]
  817. [Display(Order = 2)]
  818. public int Second { get; set; }
  819. [Required]
  820. [Display(Order = 1)]
  821. public string First { get; set; }
  822. [Required]
  823. [Display(Order = 4)]
  824. public string Fourth { get; set; }
  825. [Required]
  826. [Display(Order = 3)]
  827. public string Third { get; set; }
  828. }
  829. private static ViewDataDictionary<ValidationModel> GetViewDataWithNullModelState()
  830. {
  831. ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
  832. viewData.ModelState["foo"] = null;
  833. return viewData;
  834. }
  835. private static ViewDataDictionary<ValidationModel> GetViewDataWithModelErrors()
  836. {
  837. ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
  838. ModelState modelStateFoo = new ModelState();
  839. ModelState modelStateBar = new ModelState();
  840. ModelState modelStateBaz = new ModelState();
  841. modelStateFoo.Errors.Add(new ModelError(new InvalidOperationException("foo error from exception")));
  842. modelStateFoo.Errors.Add(new ModelError("foo error <1>"));
  843. modelStateFoo.Errors.Add(new ModelError("foo error 2"));
  844. modelStateBar.Errors.Add(new ModelError("bar error <1>"));
  845. modelStateBar.Errors.Add(new ModelError("bar error 2"));
  846. viewData.ModelState["foo"] = modelStateFoo;
  847. viewData.ModelState["bar"] = modelStateBar;
  848. viewData.ModelState["baz"] = modelStateBaz;
  849. viewData.ModelState.SetModelValue("quux", new ValueProviderResult(null, "quuxValue", null));
  850. viewData.ModelState.AddModelError("quux", new InvalidOperationException("Some error text."));
  851. return viewData;
  852. }
  853. private static ViewDataDictionary<ValidationModel> GetViewDataWithModelAndPropertyErrors()
  854. {
  855. ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
  856. ModelState modelStateFoo = new ModelState();
  857. ModelState modelStateBar = new ModelState();
  858. ModelState modelStateBaz = new ModelState();
  859. modelStateFoo.Errors.Add(new ModelError("foo error <1>"));
  860. modelStateFoo.Errors.Add(new ModelError("foo error 2"));
  861. modelStateBar.Errors.Add(new ModelError("bar error <1>"));
  862. modelStateBar.Errors.Add(new ModelError("bar error 2"));
  863. viewData.ModelState["foo"] = modelStateFoo;
  864. viewData.ModelState["bar"] = modelStateBar;
  865. viewData.ModelState["baz"] = modelStateBaz;
  866. viewData.ModelState.SetModelValue("quux", new ValueProviderResult(null, "quuxValue", null));
  867. viewData.ModelState.AddModelError("quux", new InvalidOperationException("Some error text."));
  868. viewData.ModelState.AddModelError(String.Empty, "Something is wrong.");
  869. viewData.ModelState.AddModelError(String.Empty, "Something else is also wrong.");
  870. return viewData;
  871. }
  872. private static ViewDataDictionary<ValidationModel> GetViewDataWithModelErrors(string prefix)
  873. {
  874. ViewDataDictionary<ValidationModel> viewData = new ViewDataDictionary<ValidationModel>();
  875. viewData.TemplateInfo.HtmlFieldPrefix = prefix;
  876. ModelState modelStateFoo = new ModelState();
  877. ModelState modelStateBar = new ModelState();
  878. ModelState modelStateBaz = new ModelState();
  879. modelStateFoo.Errors.Add(new ModelError("foo error <1>"));
  880. modelStateFoo.Errors.Add(new ModelError("foo error 2"));
  881. modelStateBar.Errors.Add(new ModelError("bar error <1>"));
  882. modelStateBar.Errors.Add(new ModelError("bar error 2"));
  883. viewData.ModelState[prefix + ".foo"] = modelStateFoo;
  884. viewData.ModelState[prefix + ".bar"] = modelStateBar;
  885. viewData.ModelState[prefix + ".baz"] = modelStateBaz;
  886. viewData.ModelState.SetModelValue(prefix + ".quux", new ValueProviderResult(null, "quuxValue", null));
  887. viewData.ModelState.AddModelError(prefix + ".quux", new InvalidOperationException("Some error text."));
  888. return viewData;
  889. }
  890. private static ViewDataDictionary<ModelWithOrdering> GetViewDataWithModelWithDisplayOrderErrors()
  891. {
  892. ViewDataDictionary<ModelWithOrdering> viewData = new ViewDataDictionary<ModelWithOrdering>();
  893. var model = new ModelWithOrdering();
  894. // Error names for each property on ModelWithOrdering.
  895. viewData.ModelState.AddModelError("First", "Error 1");
  896. viewData.ModelState.AddModelError("Second", "Error 2");
  897. viewData.ModelState.AddModelError("Third", "Error 3");
  898. viewData.ModelState.AddModelError("Fourth", "Error 4");
  899. return viewData;
  900. }
  901. }
  902. }