PageRenderTime 65ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/test/System.Web.WebPages.Test/Validation/ValidationHelperTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 834 lines | 599 code | 128 blank | 107 comment | 17 complexity | 1edd059c6f9736047c777b91bf2fed53 MD5 | raw file
  1. using System.Collections.Specialized;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Linq;
  4. using System.Web.Mvc;
  5. using System.Web.WebPages.Html;
  6. using System.Web.WebPages.Scope;
  7. using Moq;
  8. using Xunit;
  9. using Assert = Microsoft.TestCommon.AssertEx;
  10. namespace System.Web.WebPages.Validation.Test
  11. {
  12. public class ValidationHelperTest
  13. {
  14. [Fact]
  15. public void FormFieldKeyIsCommonToModelStateAndValidationHelper()
  16. {
  17. // Arrange
  18. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  19. string key = "_FORM";
  20. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  21. // Act and Assert
  22. Assert.Equal(key, ModelStateDictionary.FormFieldKey);
  23. Assert.Equal(key, validationHelper.FormField);
  24. }
  25. [Fact]
  26. public void AddThrowsIfFieldIsEmpty()
  27. {
  28. // Arrange
  29. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  30. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  31. // Act and Assert
  32. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.Add(field: null), "field");
  33. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.Add(field: String.Empty), "field");
  34. }
  35. [Fact]
  36. public void AddThrowsIfValidatorsParamsArrayIsNull()
  37. {
  38. // Arrange
  39. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  40. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  41. // Act and Assert
  42. Assert.ThrowsArgumentNull(() => validationHelper.Add("foo", null), "validators");
  43. }
  44. [Fact]
  45. public void AddThrowsIfValidatorsAreNull()
  46. {
  47. // Arrange
  48. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  49. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  50. // Act and Assert
  51. Assert.ThrowsArgumentNull(() => validationHelper.Add("foo", Validator.Required(), null, Validator.Range(0, 10)), "validators");
  52. }
  53. [Fact]
  54. public void RequiredReturnsErrorMessageIfFieldIsNotPresentInForm()
  55. {
  56. // Arrange
  57. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  58. string message = "Foo is required.";
  59. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  60. // Act
  61. validationHelper.RequireField("foo", message);
  62. var results = validationHelper.Validate();
  63. // Assert
  64. Assert.Equal(1, results.Count());
  65. Assert.Equal(message, results.First().ErrorMessage);
  66. }
  67. [Fact]
  68. public void RequiredReturnsErrorMessageIfFieldIsEmpty()
  69. {
  70. // Arrange
  71. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  72. string message = "Foo is required.";
  73. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "" }));
  74. // Act
  75. validationHelper.RequireField("foo", message);
  76. var results = validationHelper.Validate();
  77. // Assert
  78. Assert.Equal(1, results.Count());
  79. Assert.Equal(message, results.First().ErrorMessage);
  80. }
  81. [Fact]
  82. public void RequiredReturnsNoValidationResultsIfFieldIsPresent()
  83. {
  84. // Arrange
  85. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  86. string message = "Foo is required.";
  87. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "some value" }));
  88. // Act
  89. validationHelper.RequireField("foo", message);
  90. var results = validationHelper.Validate();
  91. // Assert
  92. Assert.Equal(0, results.Count());
  93. }
  94. [Fact]
  95. public void RequiredUsesDefaultErrorMessageIfNoValueIsProvided()
  96. {
  97. // Arrange
  98. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  99. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  100. // Act
  101. validationHelper.RequireField("foo");
  102. var results = validationHelper.Validate();
  103. // Assert
  104. Assert.Equal(1, results.Count());
  105. Assert.Equal("This field is required.", results.First().ErrorMessage);
  106. }
  107. [Fact]
  108. public void RequiredReturnsValidationResultForEachFieldThatFailed()
  109. {
  110. // Arrange
  111. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  112. string message = "This field is required.";
  113. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  114. // Act
  115. validationHelper.RequireFields("foo", "bar");
  116. var results = validationHelper.Validate();
  117. // Assert
  118. Assert.Equal(2, results.Count());
  119. Assert.Equal(message, results.First().ErrorMessage);
  120. Assert.Equal("foo", results.First().MemberNames.Single());
  121. Assert.Equal(message, results.Last().ErrorMessage);
  122. Assert.Equal("bar", results.Last().MemberNames.Single());
  123. }
  124. [Fact]
  125. public void RequiredReturnsValidationResultForEachFieldThatFailedWhenFieldsIsEmpty()
  126. {
  127. // Arrange
  128. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  129. string message = "This field is required.";
  130. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  131. // Act
  132. validationHelper.RequireFields("foo", "bar");
  133. var results = validationHelper.Validate(fields: null);
  134. // Assert
  135. Assert.Equal(2, results.Count());
  136. Assert.Equal(message, results.First().ErrorMessage);
  137. Assert.Equal("foo", results.First().MemberNames.Single());
  138. Assert.Equal(message, results.Last().ErrorMessage);
  139. Assert.Equal("bar", results.Last().MemberNames.Single());
  140. }
  141. [Fact]
  142. public void GetValidationHtmlThrowsIfArgumentIsNullOrEmpty()
  143. {
  144. // Arrange
  145. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  146. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  147. // Act and Assert
  148. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.For(field: null), "field");
  149. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.For(field: String.Empty), "field");
  150. }
  151. [Fact]
  152. public void RequireFieldThrowsIfValueIsNullOrEmpty()
  153. {
  154. // Arrange
  155. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  156. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  157. // Act and Assert
  158. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.RequireField(field: null), "field");
  159. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.RequireField(field: String.Empty), "field");
  160. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.RequireField(field: null, errorMessage: "baz"), "field");
  161. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.RequireField(field: String.Empty, errorMessage: null), "field");
  162. }
  163. [Fact]
  164. public void RequireFieldsThrowsIfFieldsAreNullOrHasEmptyValues()
  165. {
  166. // Arrange
  167. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  168. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  169. // Act and Assert
  170. Assert.ThrowsArgumentNull(() => validationHelper.RequireFields(fields: null), "fields");
  171. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.RequireFields(fields: new[] { "foo", null }), "field");
  172. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.RequireFields(fields: new[] { "foo", "" }), "field");
  173. }
  174. [Fact]
  175. public void AddThrowsIfFieldIsNullOrEmpty()
  176. {
  177. // Arrange
  178. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  179. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  180. // Act and Assert
  181. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.Add(field: null), "field");
  182. Assert.ThrowsArgumentNullOrEmptyString(() => validationHelper.Add(field: String.Empty), "field");
  183. }
  184. [Fact]
  185. public void AddThrowsIfValidatorsIsNullOrAnyValidatorIsNull()
  186. {
  187. // Arrange
  188. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  189. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  190. // Act and Assert
  191. Assert.ThrowsArgumentNull(() => validationHelper.Add(field: "foo", validators: null), "validators");
  192. Assert.ThrowsArgumentNull(() => validationHelper.Add(field: "foo", validators: new[] { Validator.DateTime(), null }), "validators");
  193. }
  194. [Fact]
  195. public void AddFormErrorCallsMethodInUnderlyingModelStateDictionary()
  196. {
  197. // Arrange
  198. var message = "This is a form error.";
  199. var dictionary = new ModelStateDictionary();
  200. ValidationHelper validationHelper = GetValidationHelper(GetContext(), dictionary);
  201. // Act
  202. validationHelper.AddFormError(message);
  203. // Assert
  204. Assert.Equal(message, dictionary["_FORM"].Errors.Single());
  205. }
  206. [Fact]
  207. public void GetValidationHtmlForRequired()
  208. {
  209. // Arrange
  210. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  211. string message = "Foo is required.";
  212. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  213. // Act
  214. validationHelper.RequireField("foo", message);
  215. var validationHtml = validationHelper.For("foo");
  216. // Assert
  217. Assert.Equal(@"data-val-required=""Foo is required."" data-val=""true""", validationHtml.ToString());
  218. }
  219. [Fact]
  220. public void ValidateReturnsAnEmptySequenceIfNoValidationsAreRegistered()
  221. {
  222. // Arrange
  223. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  224. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  225. // Act
  226. var results = validationHelper.Validate();
  227. // Assert
  228. Assert.False(results.Any());
  229. }
  230. [Fact]
  231. public void ValidatePopulatesModelStateDictionary()
  232. {
  233. // Arrange
  234. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  235. var modelStateDictionary = new ModelStateDictionary();
  236. ValidationHelper validationHelper = GetValidationHelper(GetContext(), modelStateDictionary);
  237. // Act
  238. validationHelper.RequireFields(new[] { "foo", "bar" });
  239. validationHelper.Validate();
  240. // Assert
  241. Assert.False(modelStateDictionary.IsValid);
  242. Assert.False(modelStateDictionary.IsValidField("foo"));
  243. Assert.False(modelStateDictionary.IsValidField("bar"));
  244. Assert.Equal("This field is required.", modelStateDictionary["foo"].Errors.Single());
  245. Assert.Equal("This field is required.", modelStateDictionary["bar"].Errors.Single());
  246. }
  247. [Fact]
  248. public void IsValidPopulatesModelStateDictionary()
  249. {
  250. // Arrange
  251. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  252. var modelStateDictionary = new ModelStateDictionary();
  253. ValidationHelper validationHelper = GetValidationHelper(GetContext(), modelStateDictionary);
  254. // Act
  255. validationHelper.RequireFields("foo", "bar");
  256. validationHelper.IsValid();
  257. // Assert
  258. Assert.False(modelStateDictionary.IsValid);
  259. Assert.False(modelStateDictionary.IsValidField("foo"));
  260. Assert.False(modelStateDictionary.IsValidField("bar"));
  261. Assert.Equal("This field is required.", modelStateDictionary["foo"].Errors.Single());
  262. Assert.Equal("This field is required.", modelStateDictionary["bar"].Errors.Single());
  263. }
  264. [Fact]
  265. public void GetErrorsPopulatesModelStateDictionary()
  266. {
  267. // Arrange
  268. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  269. var modelStateDictionary = new ModelStateDictionary();
  270. ValidationHelper validationHelper = GetValidationHelper(GetContext(), modelStateDictionary);
  271. // Act
  272. validationHelper.RequireFields("foo", "bar");
  273. validationHelper.GetErrors();
  274. // Assert
  275. Assert.False(modelStateDictionary.IsValid);
  276. Assert.False(modelStateDictionary.IsValidField("foo"));
  277. Assert.False(modelStateDictionary.IsValidField("bar"));
  278. Assert.Equal("This field is required.", modelStateDictionary["foo"].Errors.Single());
  279. Assert.Equal("This field is required.", modelStateDictionary["bar"].Errors.Single());
  280. }
  281. [Fact]
  282. public void GetErrorsReturnsAnEmptySequenceIfNoValidationsAreRegistered()
  283. {
  284. // Arrange
  285. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  286. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  287. // Act
  288. var results = validationHelper.GetErrors();
  289. // Assert
  290. Assert.False(results.Any());
  291. }
  292. [Fact]
  293. public void GetErrorsReturnsErrorsAddedViaAddError()
  294. {
  295. // Arrange
  296. var modelStateDictionary = new ModelStateDictionary();
  297. ValidationHelper validationHelper = GetValidationHelper(GetContext(), modelStateDictionary);
  298. // Act
  299. modelStateDictionary.AddError("foo", "Foo error");
  300. var errors = validationHelper.GetErrors("foo");
  301. // Assert
  302. Assert.Equal(new[] { "Foo error" }, errors);
  303. }
  304. [Fact]
  305. public void GetErrorsReturnsFormErrors()
  306. {
  307. // Arrange
  308. string error = "Unable to connect to remote servers.";
  309. var modelStateDictionary = new ModelStateDictionary();
  310. ValidationHelper validationHelper = GetValidationHelper(GetContext(), modelStateDictionary);
  311. // Act
  312. validationHelper.AddFormError(error);
  313. var errors = validationHelper.GetErrors();
  314. // Assert
  315. Assert.Equal(error, errors.Single());
  316. }
  317. [Fact]
  318. public void InvokingValidateMultipleTimesDoesNotCauseErrorMessagesToBeDuplicated()
  319. {
  320. // Arrange
  321. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  322. var modelStateDictionary = new ModelStateDictionary();
  323. ValidationHelper validationHelper = GetValidationHelper(GetContext(), modelStateDictionary);
  324. // Act
  325. validationHelper.RequireField("foo", "Foo is required.");
  326. validationHelper.RequireField("bar", "Bar is required.");
  327. validationHelper.Validate();
  328. Assert.False(validationHelper.IsValid());
  329. validationHelper.Validate();
  330. validationHelper.Validate();
  331. // Assert
  332. Assert.False(modelStateDictionary.IsValid);
  333. Assert.False(modelStateDictionary.IsValidField("foo"));
  334. Assert.False(modelStateDictionary.IsValidField("bar"));
  335. Assert.Equal("Foo is required.", modelStateDictionary["foo"].Errors.Single());
  336. Assert.Equal("Bar is required.", modelStateDictionary["bar"].Errors.Single());
  337. }
  338. [Fact]
  339. public void AddWorksForCustomValidator()
  340. {
  341. // Arrange
  342. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  343. string message = "Foo is not an odd number.";
  344. var oddValidator = new Mock<IValidator>();
  345. oddValidator.Setup(c => c.Validate(It.IsAny<ValidationContext>())).Returns<ValidationContext>(v =>
  346. {
  347. Assert.IsAssignableFrom<HttpContextBase>(v.ObjectInstance);
  348. var context = (HttpContextBase)v.ObjectInstance;
  349. var value = Int32.Parse(context.Request.Form["foo"]);
  350. if (value % 2 != 0)
  351. {
  352. return ValidationResult.Success;
  353. }
  354. return new ValidationResult(message);
  355. }).Verifiable();
  356. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "6" }));
  357. // Act
  358. validationHelper.Add("foo", oddValidator.Object);
  359. var result = validationHelper.Validate();
  360. // Assert
  361. Assert.Equal(1, result.Count());
  362. Assert.Equal(message, result.First().ErrorMessage);
  363. oddValidator.Verify();
  364. }
  365. [Fact]
  366. public void ValidateRunsForSpecifiedFields()
  367. {
  368. // Arrange
  369. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  370. string message = "Foo is not an odd number.";
  371. var oddValidator = new Mock<IValidator>();
  372. oddValidator.Setup(c => c.Validate(It.IsAny<ValidationContext>())).Returns<ValidationContext>(v =>
  373. {
  374. Assert.IsAssignableFrom<HttpContextBase>(v.ObjectInstance);
  375. var context = (HttpContextBase)v.ObjectInstance;
  376. if (context.Request.Form["foo"].IsEmpty())
  377. {
  378. return ValidationResult.Success;
  379. }
  380. int value = context.Request.Form["foo"].AsInt();
  381. if (value % 2 != 0)
  382. {
  383. return ValidationResult.Success;
  384. }
  385. return new ValidationResult(message);
  386. }).Verifiable();
  387. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "", bar = "" }));
  388. // Act
  389. validationHelper.Add(new[] { "foo", "bar" }, oddValidator.Object);
  390. validationHelper.RequireField("foo");
  391. var result = validationHelper.Validate("foo");
  392. // Assert
  393. Assert.Equal(1, result.Count());
  394. Assert.Equal("This field is required.", result.First().ErrorMessage);
  395. }
  396. [Fact]
  397. public void GetErrorsReturnsAllErrorsIfNoParametersAreSpecified()
  398. {
  399. // Arrange
  400. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  401. string message = "Foo is not an odd number.";
  402. var oddValidator = new Mock<IValidator>();
  403. oddValidator.Setup(c => c.Validate(It.IsAny<ValidationContext>())).Returns<ValidationContext>(v =>
  404. {
  405. Assert.IsAssignableFrom<HttpContextBase>(v.ObjectInstance);
  406. var context = (HttpContextBase)v.ObjectInstance;
  407. if (context.Request.Form["foo"].IsEmpty())
  408. {
  409. return ValidationResult.Success;
  410. }
  411. int value = context.Request.Form["foo"].AsInt();
  412. if (value % 2 != 0)
  413. {
  414. return ValidationResult.Success;
  415. }
  416. return new ValidationResult(message);
  417. }).Verifiable();
  418. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "4", bar = "" }));
  419. // Act
  420. validationHelper.Add("foo", oddValidator.Object);
  421. validationHelper.RequireFields(new[] { "bar", "foo" });
  422. var result = validationHelper.GetErrors();
  423. // Assert
  424. Assert.Equal(2, result.Count());
  425. Assert.Equal("Foo is not an odd number.", result.First());
  426. Assert.Equal("This field is required.", result.Last());
  427. }
  428. [Fact]
  429. public void IsValidReturnsTrueIfAllValuesPassValidation()
  430. {
  431. // Arrange
  432. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  433. string message = "Foo is not an odd number.";
  434. var oddValidator = new Mock<IValidator>();
  435. oddValidator.Setup(c => c.Validate(It.IsAny<ValidationContext>())).Returns<ValidationContext>(v =>
  436. {
  437. Assert.IsAssignableFrom<HttpContextBase>(v.ObjectInstance);
  438. var context = (HttpContextBase)v.ObjectInstance;
  439. if (context.Request.Form["foo"].IsEmpty())
  440. {
  441. return ValidationResult.Success;
  442. }
  443. int value = context.Request.Form["foo"].AsInt();
  444. if (value % 2 != 0)
  445. {
  446. return ValidationResult.Success;
  447. }
  448. return new ValidationResult(message);
  449. }).Verifiable();
  450. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "5", bar = "2" }));
  451. // Act
  452. validationHelper.Add(new[] { "foo", "bar" }, oddValidator.Object);
  453. validationHelper.RequireField("foo");
  454. var result = validationHelper.IsValid();
  455. // Assert
  456. Assert.True(result);
  457. }
  458. [Fact]
  459. public void IsValidValidatesSpecifiedFields()
  460. {
  461. // Arrange
  462. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  463. string message = "Foo is not an odd number.";
  464. var oddValidator = new Mock<IValidator>();
  465. oddValidator.Setup(c => c.Validate(It.IsAny<ValidationContext>())).Returns<ValidationContext>(v =>
  466. {
  467. Assert.IsAssignableFrom<HttpContextBase>(v.ObjectInstance);
  468. var context = (HttpContextBase)v.ObjectInstance;
  469. int value;
  470. if (!Int32.TryParse(context.Request.Form["foo"], out value))
  471. {
  472. return ValidationResult.Success;
  473. }
  474. if (value % 2 != 0)
  475. {
  476. return ValidationResult.Success;
  477. }
  478. return new ValidationResult(message);
  479. }).Verifiable();
  480. ValidationHelper validationHelper = GetValidationHelper(GetContext(new { foo = "3", bar = "" }));
  481. // Act
  482. validationHelper.Add(new[] { "foo", "bar" }, oddValidator.Object);
  483. validationHelper.RequireFields(new[] { "foo", "bar" });
  484. var result = validationHelper.IsValid("foo");
  485. // Assert
  486. Assert.True(result);
  487. }
  488. [Fact]
  489. public void GetValidationHtmlReturnsNullIfNoRulesAreRegistered()
  490. {
  491. // Arrange
  492. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  493. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  494. // Assert
  495. var validationAttributes = validationHelper.For("bar");
  496. // Assert
  497. Assert.Null(validationAttributes);
  498. }
  499. [Fact]
  500. public void GetValidationHtmlReturnsAttributesForRegisteredValidators()
  501. {
  502. // Arrange
  503. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  504. var validator = new Mock<IValidator>();
  505. var clientRules = new ModelClientValidationRule { ValidationType = "foo", ErrorMessage = "Foo error." };
  506. clientRules.ValidationParameters["qux"] = "some data";
  507. validator.Setup(c => c.ClientValidationRule).Returns(clientRules).Verifiable();
  508. var expected = @"data-val-required=""This field is required."" data-val-foo=""Foo error."" data-val-foo-qux=""some data"" data-val=""true""";
  509. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  510. // Act
  511. validationHelper.RequireField("foo");
  512. validationHelper.Add("foo", validator.Object);
  513. var validationAttributes = validationHelper.For("foo");
  514. // Assert
  515. Assert.Equal(expected, validationAttributes.ToString());
  516. }
  517. [Fact]
  518. public void GetValidationHtmlHtmlEncodesAttributeValues()
  519. {
  520. // Arrange
  521. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  522. var validator = new Mock<IValidator>();
  523. var clientRules = new ModelClientValidationRule { ValidationType = "biz", ErrorMessage = "<Biz error.>" };
  524. clientRules.ValidationParameters["qux"] = "<some ' data>";
  525. validator.Setup(c => c.ClientValidationRule).Returns(clientRules).Verifiable();
  526. var expected = @"data-val-required=""This field is required."" data-val-biz=""&lt;Biz error.&gt;"" data-val-biz-qux=""&lt;some &#39; data&gt;"" data-val=""true""";
  527. // Act
  528. ValidationHelper validationHelper = GetValidationHelper(GetContext());
  529. // Assert
  530. validationHelper.RequireField("foo");
  531. validationHelper.Add("foo", validator.Object);
  532. var validationAttributes = validationHelper.For("foo");
  533. // Assert
  534. Assert.Equal(expected, validationAttributes.ToString());
  535. }
  536. [Fact]
  537. public void GetValidationFromClientValidationRulesThrowsIfValidationTypeIsNullOrEmpty()
  538. {
  539. // Arrange
  540. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  541. var clientRule = new ModelClientValidationRule { ValidationType = null };
  542. // Act and Assert
  543. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  544. "Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: System.Web.Mvc.ModelClientValidationRule");
  545. clientRule.ValidationType = String.Empty;
  546. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  547. "Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: System.Web.Mvc.ModelClientValidationRule");
  548. }
  549. [Fact]
  550. public void GetValidationFromClientValidationRulesThrowsIfSameValidationTypeIsSpecifiedMultipleTimes()
  551. {
  552. // Arrange
  553. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  554. var clientRule1 = new ModelClientValidationRule { ValidationType = "foo" };
  555. var clientRule2 = new ModelClientValidationRule { ValidationType = "foo" };
  556. // Act and Assert
  557. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule1, clientRule2 }),
  558. "Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: foo");
  559. }
  560. [Fact]
  561. public void GetValidationFromClientValidationRulesThrowsIfValidationTypeDoesNotContainAllLowerCaseCharacters()
  562. {
  563. // Arrange
  564. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  565. var clientRule = new ModelClientValidationRule { ValidationType = "Foo" };
  566. // Act and Assert
  567. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  568. "Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: \"Foo\", client rule type: System.Web.Mvc.ModelClientValidationRule");
  569. clientRule.ValidationType = "bAr";
  570. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  571. "Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: \"bAr\", client rule type: System.Web.Mvc.ModelClientValidationRule");
  572. clientRule.ValidationType = "bar123";
  573. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  574. "Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: \"bar123\", client rule type: System.Web.Mvc.ModelClientValidationRule");
  575. }
  576. [Fact]
  577. public void GetValidationFromClientValidationRulesThrowsIfValidationParamaterContainsNonAlphaNumericCharacters()
  578. {
  579. // Arrange
  580. RequestFieldValidatorBase.IgnoreUseUnvalidatedValues = true;
  581. var clientRule = new ModelClientValidationRule { ValidationType = "required" };
  582. clientRule.ValidationParameters["min^"] = "some-val";
  583. // Act and Assert
  584. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  585. "Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: min^, client rule type: System.Web.Mvc.ModelClientValidationRule");
  586. clientRule.ValidationParameters.Clear();
  587. clientRule.ValidationParameters["Min"] = "some-val";
  588. Assert.Throws<InvalidOperationException>(() => ValidationHelper.GenerateHtmlFromClientValidationRules(new[] { clientRule }),
  589. "Validation parameter names in unobtrusive client validation rules must start with a lowercase letter and consist of only lowercase letters or digits. Validation parameter name: Min, client rule type: System.Web.Mvc.ModelClientValidationRule");
  590. }
  591. [Fact]
  592. public void DefaultValidCssClassIsNull()
  593. {
  594. Assert.Null(ValidationHelper.ValidCssClass);
  595. }
  596. [Fact]
  597. public void DefaultInvalidCssClassIsSameAsHtmlHelper()
  598. {
  599. Assert.Equal(HtmlHelper.DefaultValidationInputErrorCssClass, ValidationHelper.InvalidCssClass);
  600. }
  601. [Fact]
  602. public void InvalidCssClassIsNullIfExplicitlySetToNull()
  603. {
  604. using (ValidationHelper.OverrideScope())
  605. {
  606. ValidationHelper.InvalidCssClass = null;
  607. Assert.Null(ValidationHelper.InvalidCssClass);
  608. }
  609. }
  610. [Fact]
  611. public void ValidCssClassIsScopeBacked()
  612. {
  613. // Set a value
  614. string old = ValidationHelper.ValidCssClass;
  615. ValidationHelper.ValidCssClass = "outer";
  616. using (ScopeStorage.CreateTransientScope())
  617. {
  618. ValidationHelper.ValidCssClass = "inner";
  619. Assert.Equal("inner", ValidationHelper.ValidCssClass);
  620. }
  621. Assert.Equal("outer", ValidationHelper.ValidCssClass);
  622. ValidationHelper.ValidCssClass = old;
  623. }
  624. [Fact]
  625. public void InvalidCssClassIsScopeBacked()
  626. {
  627. // Set a value
  628. string old = ValidationHelper.InvalidCssClass;
  629. ValidationHelper.InvalidCssClass = "outer";
  630. using (ScopeStorage.CreateTransientScope())
  631. {
  632. ValidationHelper.InvalidCssClass = "inner";
  633. Assert.Equal("inner", ValidationHelper.InvalidCssClass);
  634. }
  635. Assert.Equal("outer", ValidationHelper.InvalidCssClass);
  636. ValidationHelper.InvalidCssClass = old;
  637. }
  638. [Fact]
  639. public void ClassForReturnsNullIfNotPost()
  640. {
  641. // Arrange
  642. ValidationHelper helper = GetValidationHelper();
  643. // Act/Assert
  644. Assert.Null(helper.ClassFor("foo"));
  645. }
  646. [Fact]
  647. public void ClassForReturnsValidClassNameIfNoErrorsAddedForField()
  648. {
  649. // Arrange
  650. ValidationHelper helper = GetPostValidationHelper();
  651. // Act/Assert
  652. HtmlString html = helper.ClassFor("foo");
  653. string str = html == null ? null : html.ToHtmlString();
  654. Assert.Equal(ValidationHelper.ValidCssClass, str);
  655. }
  656. [Fact]
  657. public void ClassForReturnsInvalidClassNameIfFieldHasErrors()
  658. {
  659. // Arrange
  660. ValidationHelper helper = GetPostValidationHelper();
  661. helper.Add("foo", new AutoFailValidator());
  662. // Act/Assert
  663. Assert.Equal(ValidationHelper.InvalidCssClass, helper.ClassFor("foo").ToHtmlString());
  664. }
  665. private static ValidationHelper GetPostValidationHelper()
  666. {
  667. HttpContextBase context = GetContext();
  668. Mock.Get(context.Request).SetupGet(c => c.HttpMethod).Returns("POST");
  669. ValidationHelper helper = GetValidationHelper(httpContext: context);
  670. return helper;
  671. }
  672. private static HttpContextBase GetContext(object formValues = null)
  673. {
  674. var context = new Mock<HttpContextBase>();
  675. var request = new Mock<HttpRequestBase>();
  676. var nameValueCollection = new NameValueCollection();
  677. if (formValues != null)
  678. {
  679. foreach (var prop in formValues.GetType().GetProperties())
  680. {
  681. nameValueCollection.Add(prop.Name, prop.GetValue(formValues, null).ToString());
  682. }
  683. }
  684. request.SetupGet(c => c.Form).Returns(nameValueCollection);
  685. context.SetupGet(c => c.Request).Returns(request.Object);
  686. return context.Object;
  687. }
  688. private static ValidationHelper GetValidationHelper(HttpContextBase httpContext = null, ModelStateDictionary modelStateDictionary = null)
  689. {
  690. httpContext = httpContext ?? GetContext();
  691. modelStateDictionary = modelStateDictionary ?? new ModelStateDictionary();
  692. return new ValidationHelper(httpContext, modelStateDictionary);
  693. }
  694. private class AutoFailValidator : IValidator
  695. {
  696. public ValidationResult Validate(ValidationContext validationContext)
  697. {
  698. return new ValidationResult("Failed!");
  699. }
  700. public ModelClientValidationRule ClientValidationRule
  701. {
  702. get { throw new NotImplementedException(); }
  703. }
  704. }
  705. }
  706. }