PageRenderTime 47ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/test/System.Web.Mvc.Test/Test/HtmlHelperTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 1172 lines | 832 code | 181 blank | 159 comment | 0 complexity | 9b8ec657ea3ca6ad5ac32709873f877f MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Threading;
  7. using System.Web.Routing;
  8. using Microsoft.Web.UnitTestUtil;
  9. using Moq;
  10. using Xunit;
  11. using Assert = Microsoft.TestCommon.AssertEx;
  12. namespace System.Web.Mvc.Test
  13. {
  14. public class HtmlHelperTest
  15. {
  16. public static readonly RouteValueDictionary AttributesDictionary = new RouteValueDictionary(new { baz = "BazValue" });
  17. public static readonly object AttributesObjectDictionary = new { baz = "BazObjValue" };
  18. public static readonly object AttributesObjectUnderscoresDictionary = new { foo_baz = "BazObjValue" };
  19. // Constructor
  20. [Fact]
  21. public void ConstructorGuardClauses()
  22. {
  23. // Arrange
  24. var viewContext = new Mock<ViewContext>().Object;
  25. var viewDataContainer = MvcHelper.GetViewDataContainer(null);
  26. // Act & Assert
  27. Assert.ThrowsArgumentNull(
  28. () => new HtmlHelper(null, viewDataContainer),
  29. "viewContext"
  30. );
  31. Assert.ThrowsArgumentNull(
  32. () => new HtmlHelper(viewContext, null),
  33. "viewDataContainer"
  34. );
  35. Assert.ThrowsArgumentNull(
  36. () => new HtmlHelper(viewContext, viewDataContainer, null),
  37. "routeCollection"
  38. );
  39. }
  40. [Fact]
  41. public void PropertiesAreSet()
  42. {
  43. // Arrange
  44. var viewContext = new Mock<ViewContext>().Object;
  45. var viewData = new ViewDataDictionary<String>("The Model");
  46. var routes = new RouteCollection();
  47. var mockViewDataContainer = new Mock<IViewDataContainer>();
  48. mockViewDataContainer.Setup(vdc => vdc.ViewData).Returns(viewData);
  49. // Act
  50. var htmlHelper = new HtmlHelper(viewContext, mockViewDataContainer.Object, routes);
  51. // Assert
  52. Assert.Equal(viewContext, htmlHelper.ViewContext);
  53. Assert.Equal(mockViewDataContainer.Object, htmlHelper.ViewDataContainer);
  54. Assert.Equal(routes, htmlHelper.RouteCollection);
  55. Assert.Equal(viewData.Model, htmlHelper.ViewData.Model);
  56. }
  57. [Fact]
  58. public void DefaultRouteCollectionIsRouteTableRoutes()
  59. {
  60. // Arrange
  61. var viewContext = new Mock<ViewContext>().Object;
  62. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  63. // Act
  64. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  65. // Assert
  66. Assert.Equal(RouteTable.Routes, htmlHelper.RouteCollection);
  67. }
  68. // AnonymousObjectToHtmlAttributes tests
  69. [Fact]
  70. public void ConvertsUnderscoresInNamesToDashes()
  71. {
  72. // Arrange
  73. var attributes = new { foo = "Bar", baz_bif = "pow_wow" };
  74. // Act
  75. RouteValueDictionary result = HtmlHelper.AnonymousObjectToHtmlAttributes(attributes);
  76. // Assert
  77. Assert.Equal(2, result.Count);
  78. Assert.Equal("Bar", result["foo"]);
  79. Assert.Equal("pow_wow", result["baz-bif"]);
  80. }
  81. // AttributeEncode
  82. [Fact]
  83. public void AttributeEncodeObject()
  84. {
  85. // Arrange
  86. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  87. // Act
  88. string encodedHtml = htmlHelper.AttributeEncode((object)@"<"">");
  89. // Assert
  90. Assert.Equal(encodedHtml, "&lt;&quot;>");
  91. }
  92. [Fact]
  93. public void AttributeEncodeObjectNull()
  94. {
  95. // Arrange
  96. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  97. // Act
  98. string encodedHtml = htmlHelper.AttributeEncode((object)null);
  99. // Assert
  100. Assert.Equal("", encodedHtml);
  101. }
  102. [Fact]
  103. public void AttributeEncodeString()
  104. {
  105. // Arrange
  106. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  107. // Act
  108. string encodedHtml = htmlHelper.AttributeEncode(@"<"">");
  109. // Assert
  110. Assert.Equal(encodedHtml, "&lt;&quot;>");
  111. }
  112. [Fact]
  113. public void AttributeEncodeStringNull()
  114. {
  115. // Arrange
  116. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  117. // Act
  118. string encodedHtml = htmlHelper.AttributeEncode((string)null);
  119. // Assert
  120. Assert.Equal("", encodedHtml);
  121. }
  122. // EnableClientValidation
  123. [Fact]
  124. public void EnableClientValidation()
  125. {
  126. // Arrange
  127. var mockViewContext = new Mock<ViewContext>();
  128. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  129. var htmlHelper = new HtmlHelper(mockViewContext.Object, viewDataContainer);
  130. // Act
  131. htmlHelper.EnableClientValidation();
  132. // Act & assert
  133. mockViewContext.VerifySet(vc => vc.ClientValidationEnabled = true);
  134. }
  135. // EnableUnobtrusiveJavaScript
  136. [Fact]
  137. public void EnableUnobtrusiveJavaScript()
  138. {
  139. // Arrange
  140. var mockViewContext = new Mock<ViewContext>();
  141. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  142. var htmlHelper = new HtmlHelper(mockViewContext.Object, viewDataContainer);
  143. // Act
  144. htmlHelper.EnableUnobtrusiveJavaScript();
  145. // Act & assert
  146. mockViewContext.VerifySet(vc => vc.UnobtrusiveJavaScriptEnabled = true);
  147. }
  148. // Encode
  149. [Fact]
  150. public void EncodeObject()
  151. {
  152. // Arrange
  153. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  154. // Act
  155. string encodedHtml = htmlHelper.Encode((object)"<br />");
  156. // Assert
  157. Assert.Equal(encodedHtml, "&lt;br /&gt;");
  158. }
  159. [Fact]
  160. public void EncodeObjectNull()
  161. {
  162. // Arrange
  163. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  164. // Act
  165. string encodedHtml = htmlHelper.Encode((object)null);
  166. // Assert
  167. Assert.Equal("", encodedHtml);
  168. }
  169. [Fact]
  170. public void EncodeString()
  171. {
  172. // Arrange
  173. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  174. // Act
  175. string encodedHtml = htmlHelper.Encode("<br />");
  176. // Assert
  177. Assert.Equal(encodedHtml, "&lt;br /&gt;");
  178. }
  179. [Fact]
  180. public void EncodeStringNull()
  181. {
  182. // Arrange
  183. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper();
  184. // Act
  185. string encodedHtml = htmlHelper.Encode((string)null);
  186. // Assert
  187. Assert.Equal("", encodedHtml);
  188. }
  189. // GetModelStateValue
  190. [Fact]
  191. public void GetModelStateValueReturnsNullIfModelStateHasNoValue()
  192. {
  193. // Arrange
  194. ViewDataDictionary vdd = new ViewDataDictionary();
  195. vdd.ModelState.AddModelError("foo", "some error text"); // didn't call SetModelValue()
  196. HtmlHelper helper = new HtmlHelper(new ViewContext(), new SimpleViewDataContainer(vdd));
  197. // Act
  198. object retVal = helper.GetModelStateValue("foo", typeof(object));
  199. // Assert
  200. Assert.Null(retVal);
  201. }
  202. [Fact]
  203. public void GetModelStateValueReturnsNullIfModelStateKeyNotPresent()
  204. {
  205. // Arrange
  206. ViewDataDictionary vdd = new ViewDataDictionary();
  207. HtmlHelper helper = new HtmlHelper(new ViewContext(), new SimpleViewDataContainer(vdd));
  208. // Act
  209. object retVal = helper.GetModelStateValue("key_not_present", typeof(object));
  210. // Assert
  211. Assert.Null(retVal);
  212. }
  213. // GenerateIdFromName
  214. [Fact]
  215. public void GenerateIdFromNameTests()
  216. {
  217. // Guard clauses
  218. Assert.ThrowsArgumentNull(
  219. () => HtmlHelper.GenerateIdFromName(null),
  220. "name"
  221. );
  222. Assert.ThrowsArgumentNull(
  223. () => HtmlHelper.GenerateIdFromName(null, "?"),
  224. "name"
  225. );
  226. Assert.ThrowsArgumentNull(
  227. () => HtmlHelper.GenerateIdFromName("?", null),
  228. "idAttributeDotReplacement"
  229. );
  230. // Default replacement tests
  231. Assert.Equal("", HtmlHelper.GenerateIdFromName(""));
  232. Assert.Equal("Foo", HtmlHelper.GenerateIdFromName("Foo"));
  233. Assert.Equal("Foo_Bar", HtmlHelper.GenerateIdFromName("Foo.Bar"));
  234. Assert.Equal("Foo_Bar_Baz", HtmlHelper.GenerateIdFromName("Foo.Bar.Baz"));
  235. Assert.Null(HtmlHelper.GenerateIdFromName("1Foo"));
  236. Assert.Equal("Foo_0_", HtmlHelper.GenerateIdFromName("Foo[0]"));
  237. // Custom replacement tests
  238. Assert.Equal("", HtmlHelper.GenerateIdFromName("", "?"));
  239. Assert.Equal("Foo", HtmlHelper.GenerateIdFromName("Foo", "?"));
  240. Assert.Equal("Foo?Bar", HtmlHelper.GenerateIdFromName("Foo.Bar", "?"));
  241. Assert.Equal("Foo?Bar?Baz", HtmlHelper.GenerateIdFromName("Foo.Bar.Baz", "?"));
  242. Assert.Equal("FooBarBaz", HtmlHelper.GenerateIdFromName("Foo.Bar.Baz", ""));
  243. Assert.Null(HtmlHelper.GenerateIdFromName("1Foo", "?"));
  244. Assert.Equal("Foo?0?", HtmlHelper.GenerateIdFromName("Foo[0]", "?"));
  245. }
  246. // RenderPartialInternal
  247. [Fact]
  248. public void NullPartialViewNameThrows()
  249. {
  250. // Arrange
  251. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  252. ViewDataDictionary viewData = new ViewDataDictionary();
  253. // Act & Assert
  254. Assert.ThrowsArgumentNullOrEmpty(
  255. () => helper.RenderPartialInternal(null /* partialViewName */, null /* viewData */, null /* model */, TextWriter.Null),
  256. "partialViewName");
  257. }
  258. [Fact]
  259. public void EmptyPartialViewNameThrows()
  260. {
  261. // Arrange
  262. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  263. ViewDataDictionary viewData = new ViewDataDictionary();
  264. // Act & Assert
  265. Assert.ThrowsArgumentNullOrEmpty(
  266. () => helper.RenderPartialInternal(String.Empty /* partialViewName */, null /* viewData */, null /* model */, TextWriter.Null),
  267. "partialViewName");
  268. }
  269. [Fact]
  270. public void EngineLookupSuccessCallsRender()
  271. {
  272. // Arrange
  273. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  274. TextWriter writer = helper.ViewContext.Writer;
  275. Mock<IViewEngine> engine = new Mock<IViewEngine>(MockBehavior.Strict);
  276. Mock<IView> view = new Mock<IView>(MockBehavior.Strict);
  277. engine
  278. .Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), "partial-view", It.IsAny<bool>()))
  279. .Returns(new ViewEngineResult(view.Object, engine.Object))
  280. .Verifiable();
  281. view
  282. .Setup(v => v.Render(It.IsAny<ViewContext>(), writer))
  283. .Callback<ViewContext, TextWriter>(
  284. (viewContext, _) =>
  285. {
  286. Assert.Same(helper.ViewContext.View, viewContext.View);
  287. Assert.Same(helper.ViewContext.TempData, viewContext.TempData);
  288. })
  289. .Verifiable();
  290. // Act
  291. helper.RenderPartialInternal("partial-view", null /* viewData */, null /* model */, writer, engine.Object);
  292. // Assert
  293. engine.Verify();
  294. view.Verify();
  295. }
  296. [Fact]
  297. public void EngineLookupFailureThrows()
  298. {
  299. // Arrange
  300. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  301. Mock<IViewEngine> engine = new Mock<IViewEngine>(MockBehavior.Strict);
  302. engine
  303. .Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), "partial-view", It.IsAny<bool>()))
  304. .Returns(new ViewEngineResult(new[] { "location1", "location2" }))
  305. .Verifiable();
  306. // Act & Assert
  307. Assert.Throws<InvalidOperationException>(
  308. () => helper.RenderPartialInternal("partial-view", null /* viewData */, null /* model */, TextWriter.Null, engine.Object),
  309. @"The partial view 'partial-view' was not found or no view engine supports the searched locations. The following locations were searched:
  310. location1
  311. location2");
  312. engine.Verify();
  313. }
  314. [Fact]
  315. public void RenderPartialInternalWithNullModelAndNullViewData()
  316. {
  317. // Arrange
  318. object model = new object();
  319. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  320. helper.ViewData["Foo"] = "Bar";
  321. helper.ViewData.Model = model;
  322. Mock<IViewEngine> engine = new Mock<IViewEngine>(MockBehavior.Strict);
  323. Mock<IView> view = new Mock<IView>(MockBehavior.Strict);
  324. engine
  325. .Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), "partial-view", It.IsAny<bool>()))
  326. .Returns(new ViewEngineResult(view.Object, engine.Object))
  327. .Verifiable();
  328. view
  329. .Setup(v => v.Render(It.IsAny<ViewContext>(), TextWriter.Null))
  330. .Callback<ViewContext, TextWriter>(
  331. (viewContext, writer) =>
  332. {
  333. Assert.NotSame(helper.ViewData, viewContext.ViewData); // New view data instance
  334. Assert.Equal("Bar", viewContext.ViewData["Foo"]); // Copy of the existing view data
  335. Assert.Same(model, viewContext.ViewData.Model); // Keep existing model
  336. })
  337. .Verifiable();
  338. // Act
  339. helper.RenderPartialInternal("partial-view", null /* viewData */, null /* model */, TextWriter.Null, engine.Object);
  340. // Assert
  341. engine.Verify();
  342. view.Verify();
  343. }
  344. [Fact]
  345. public void RenderPartialInternalWithNonNullModelAndNullViewData()
  346. {
  347. // Arrange
  348. object model = new object();
  349. object newModel = new object();
  350. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  351. helper.ViewData["Foo"] = "Bar";
  352. helper.ViewData.Model = model;
  353. Mock<IViewEngine> engine = new Mock<IViewEngine>(MockBehavior.Strict);
  354. Mock<IView> view = new Mock<IView>(MockBehavior.Strict);
  355. engine
  356. .Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), "partial-view", It.IsAny<bool>()))
  357. .Returns(new ViewEngineResult(view.Object, engine.Object))
  358. .Verifiable();
  359. view
  360. .Setup(v => v.Render(It.IsAny<ViewContext>(), TextWriter.Null))
  361. .Callback<ViewContext, TextWriter>(
  362. (viewContext, writer) =>
  363. {
  364. Assert.NotSame(helper.ViewData, viewContext.ViewData); // New view data instance
  365. Assert.Empty(viewContext.ViewData); // Empty (not copied)
  366. Assert.Same(newModel, viewContext.ViewData.Model); // New model
  367. })
  368. .Verifiable();
  369. // Act
  370. helper.RenderPartialInternal("partial-view", null /* viewData */, newModel, TextWriter.Null, engine.Object);
  371. // Assert
  372. engine.Verify();
  373. view.Verify();
  374. }
  375. [Fact]
  376. public void RenderPartialInternalWithNullModelAndNonNullViewData()
  377. {
  378. // Arrange
  379. object model = new object();
  380. object vddModel = new object();
  381. ViewDataDictionary vdd = new ViewDataDictionary();
  382. vdd["Baz"] = "Biff";
  383. vdd.Model = vddModel;
  384. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  385. helper.ViewData["Foo"] = "Bar";
  386. helper.ViewData.Model = model;
  387. Mock<IViewEngine> engine = new Mock<IViewEngine>(MockBehavior.Strict);
  388. Mock<IView> view = new Mock<IView>(MockBehavior.Strict);
  389. engine
  390. .Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), "partial-view", It.IsAny<bool>()))
  391. .Returns(new ViewEngineResult(view.Object, engine.Object))
  392. .Verifiable();
  393. view
  394. .Setup(v => v.Render(It.IsAny<ViewContext>(), TextWriter.Null))
  395. .Callback<ViewContext, TextWriter>(
  396. (viewContext, writer) =>
  397. {
  398. Assert.NotSame(helper.ViewData, viewContext.ViewData); // New view data instance
  399. Assert.Single(viewContext.ViewData); // Copy of the passed view data, not original view data
  400. Assert.Equal("Biff", viewContext.ViewData["Baz"]);
  401. Assert.Same(vddModel, viewContext.ViewData.Model); // Keep model from passed view data, not original view data
  402. })
  403. .Verifiable();
  404. // Act
  405. helper.RenderPartialInternal("partial-view", vdd, null /* model */, TextWriter.Null, engine.Object);
  406. // Assert
  407. engine.Verify();
  408. view.Verify();
  409. }
  410. [Fact]
  411. public void RenderPartialInternalWithNonNullModelAndNonNullViewData()
  412. {
  413. // Arrange
  414. object model = new object();
  415. object vddModel = new object();
  416. object newModel = new object();
  417. ViewDataDictionary vdd = new ViewDataDictionary();
  418. vdd["Baz"] = "Biff";
  419. vdd.Model = vddModel;
  420. TestableHtmlHelper helper = TestableHtmlHelper.Create();
  421. helper.ViewData["Foo"] = "Bar";
  422. helper.ViewData.Model = model;
  423. Mock<IViewEngine> engine = new Mock<IViewEngine>(MockBehavior.Strict);
  424. Mock<IView> view = new Mock<IView>(MockBehavior.Strict);
  425. engine
  426. .Setup(e => e.FindPartialView(It.IsAny<ControllerContext>(), "partial-view", It.IsAny<bool>()))
  427. .Returns(new ViewEngineResult(view.Object, engine.Object))
  428. .Verifiable();
  429. view
  430. .Setup(v => v.Render(It.IsAny<ViewContext>(), TextWriter.Null))
  431. .Callback<ViewContext, TextWriter>(
  432. (viewContext, writer) =>
  433. {
  434. Assert.NotSame(helper.ViewData, viewContext.ViewData); // New view data instance
  435. Assert.Single(viewContext.ViewData); // Copy of the passed view data, not original view data
  436. Assert.Equal("Biff", viewContext.ViewData["Baz"]);
  437. Assert.Same(newModel, viewContext.ViewData.Model); // New model
  438. })
  439. .Verifiable();
  440. // Act
  441. helper.RenderPartialInternal("partial-view", vdd, newModel, TextWriter.Null, engine.Object);
  442. // Assert
  443. engine.Verify();
  444. view.Verify();
  445. }
  446. // HttpMethodOverride
  447. [Fact]
  448. public void HttpMethodOverrideGuardClauses()
  449. {
  450. // Arrange
  451. var viewContext = new Mock<ViewContext>().Object;
  452. var viewDataContainer = MvcHelper.GetViewDataContainer(null);
  453. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  454. // Act & Assert
  455. Assert.ThrowsArgumentNullOrEmpty(
  456. () => htmlHelper.HttpMethodOverride(null),
  457. "httpMethod"
  458. );
  459. Assert.Throws<ArgumentException>(
  460. () => htmlHelper.HttpMethodOverride((HttpVerbs)10000),
  461. @"The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put.
  462. Parameter name: httpVerb"
  463. );
  464. Assert.Throws<ArgumentException>(
  465. () => htmlHelper.HttpMethodOverride(HttpVerbs.Get),
  466. @"The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put.
  467. Parameter name: httpVerb"
  468. );
  469. Assert.Throws<ArgumentException>(
  470. () => htmlHelper.HttpMethodOverride(HttpVerbs.Post),
  471. @"The specified HttpVerbs value is not supported. The supported values are Delete, Head, and Put.
  472. Parameter name: httpVerb"
  473. );
  474. Assert.Throws<ArgumentException>(
  475. () => htmlHelper.HttpMethodOverride("gEt"),
  476. @"The GET and POST HTTP methods are not supported.
  477. Parameter name: httpMethod"
  478. );
  479. Assert.Throws<ArgumentException>(
  480. () => htmlHelper.HttpMethodOverride("pOsT"),
  481. @"The GET and POST HTTP methods are not supported.
  482. Parameter name: httpMethod"
  483. );
  484. }
  485. [Fact]
  486. public void HttpMethodOverrideWithMethodRendersHiddenField()
  487. {
  488. // Arrange
  489. var viewContext = new Mock<ViewContext>().Object;
  490. var viewDataContainer = MvcHelper.GetViewDataContainer(null);
  491. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  492. // Act
  493. MvcHtmlString hiddenField = htmlHelper.HttpMethodOverride("PUT");
  494. // Assert
  495. Assert.Equal(@"<input name=""X-HTTP-Method-Override"" type=""hidden"" value=""PUT"" />", hiddenField.ToHtmlString());
  496. }
  497. [Fact]
  498. public void HttpMethodOverrideWithVerbRendersHiddenField()
  499. {
  500. // Arrange
  501. var viewContext = new Mock<ViewContext>().Object;
  502. var viewDataContainer = MvcHelper.GetViewDataContainer(null);
  503. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  504. // Act
  505. MvcHtmlString hiddenField = htmlHelper.HttpMethodOverride(HttpVerbs.Delete);
  506. // Assert
  507. Assert.Equal(@"<input name=""X-HTTP-Method-Override"" type=""hidden"" value=""DELETE"" />", hiddenField.ToHtmlString());
  508. }
  509. [Fact]
  510. public void ViewBagProperty_ReflectsViewData()
  511. {
  512. // Arrange
  513. Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
  514. ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
  515. viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
  516. // Act
  517. HtmlHelper htmlHelper = new HtmlHelper(new Mock<ViewContext>().Object, viewDataContainer.Object);
  518. // Assert
  519. Assert.Equal(1, htmlHelper.ViewBag.A);
  520. }
  521. [Fact]
  522. public void ViewBagProperty_ReflectsNewViewDataContainerInstance()
  523. {
  524. // Arrange
  525. ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
  526. Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
  527. viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
  528. ViewDataDictionary otherViewDataDictionary = new ViewDataDictionary() { { "A", 2 } };
  529. Mock<IViewDataContainer> otherViewDataContainer = new Mock<IViewDataContainer>();
  530. otherViewDataContainer.Setup(container => container.ViewData).Returns(otherViewDataDictionary);
  531. HtmlHelper htmlHelper = new HtmlHelper(new Mock<ViewContext>().Object, viewDataContainer.Object, new RouteCollection());
  532. // Act
  533. htmlHelper.ViewDataContainer = otherViewDataContainer.Object;
  534. // Assert
  535. Assert.Equal(2, htmlHelper.ViewBag.A);
  536. }
  537. [Fact]
  538. public void ViewBag_PropagatesChangesToViewData()
  539. {
  540. // Arrange
  541. ViewDataDictionary viewDataDictionary = new ViewDataDictionary() { { "A", 1 } };
  542. Mock<IViewDataContainer> viewDataContainer = new Mock<IViewDataContainer>();
  543. viewDataContainer.Setup(container => container.ViewData).Returns(viewDataDictionary);
  544. HtmlHelper htmlHelper = new HtmlHelper(new Mock<ViewContext>().Object, viewDataContainer.Object, new RouteCollection());
  545. // Act
  546. htmlHelper.ViewBag.A = "foo";
  547. htmlHelper.ViewBag.B = 2;
  548. // Assert
  549. Assert.Equal("foo", htmlHelper.ViewData["A"]);
  550. Assert.Equal(2, htmlHelper.ViewData["B"]);
  551. }
  552. // Unobtrusive validation attributes
  553. [Fact]
  554. public void GetUnobtrusiveValidationAttributesReturnsEmptySetWhenClientValidationIsNotEnabled()
  555. {
  556. // Arrange
  557. var formContext = new FormContext();
  558. formContext.RenderedField("foobar", true);
  559. var viewContext = new Mock<ViewContext>();
  560. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  561. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  562. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  563. // Act
  564. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  565. // Assert
  566. Assert.Empty(result);
  567. }
  568. [Fact]
  569. public void GetUnobtrusiveValidationAttributesReturnsEmptySetWhenUnobtrusiveJavaScriptIsNotEnabled()
  570. {
  571. // Arrange
  572. var formContext = new FormContext();
  573. formContext.RenderedField("foobar", true);
  574. var viewContext = new Mock<ViewContext>();
  575. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  576. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  577. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  578. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  579. // Act
  580. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  581. // Assert
  582. Assert.Empty(result);
  583. }
  584. [Fact]
  585. public void GetUnobtrusiveValidationAttributesReturnsEmptySetWhenFieldHasAlreadyBeenRendered()
  586. {
  587. // Arrange
  588. var formContext = new FormContext();
  589. formContext.RenderedField("foobar", true);
  590. var viewContext = new Mock<ViewContext>();
  591. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  592. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  593. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  594. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  595. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  596. // Act
  597. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  598. // Assert
  599. Assert.Empty(result);
  600. }
  601. [Fact]
  602. public void GetUnobtrusiveValidationAttributesReturnsEmptySetAndSetsFieldAsRenderedForFieldWithNoClientRules()
  603. {
  604. // Arrange
  605. var formContext = new FormContext();
  606. var viewContext = new Mock<ViewContext>();
  607. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  608. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  609. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  610. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  611. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  612. htmlHelper.ClientValidationRuleFactory = delegate { return Enumerable.Empty<ModelClientValidationRule>(); };
  613. // Act
  614. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  615. // Assert
  616. Assert.Empty(result);
  617. Assert.True(formContext.RenderedField("foobar"));
  618. }
  619. [Fact]
  620. public void GetUnobtrusiveValidationAttributesIncludesDataValTrueWithNonEmptyClientRuleList()
  621. {
  622. // Arrange
  623. var formContext = new FormContext();
  624. var viewContext = new Mock<ViewContext>();
  625. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  626. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  627. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  628. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  629. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  630. htmlHelper.ClientValidationRuleFactory = delegate { return new[] { new ModelClientValidationRule { ValidationType = "type" } }; };
  631. // Act
  632. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  633. // Assert
  634. Assert.Equal("true", result["data-val"]);
  635. }
  636. [Fact]
  637. public void GetUnobtrusiveValidationAttributesWithEmptyMessage()
  638. {
  639. // Arrange
  640. var formContext = new FormContext();
  641. var viewContext = new Mock<ViewContext>();
  642. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  643. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  644. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  645. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  646. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  647. htmlHelper.ClientValidationRuleFactory = delegate { return new[] { new ModelClientValidationRule { ValidationType = "type" } }; };
  648. // Act
  649. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  650. // Assert
  651. Assert.Equal("", result["data-val-type"]);
  652. }
  653. [Fact]
  654. public void GetUnobtrusiveValidationAttributesMessageIsHtmlEncoded()
  655. {
  656. // Arrange
  657. var formContext = new FormContext();
  658. var viewContext = new Mock<ViewContext>();
  659. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  660. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  661. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  662. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  663. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  664. htmlHelper.ClientValidationRuleFactory = delegate { return new[] { new ModelClientValidationRule { ValidationType = "type", ErrorMessage = "<script>alert('xss')</script>" } }; };
  665. // Act
  666. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  667. // Assert
  668. Assert.Equal("&lt;script&gt;alert(&#39;xss&#39;)&lt;/script&gt;", result["data-val-type"]);
  669. }
  670. [Fact]
  671. public void GetUnobtrusiveValidationAttributesWithMessageAndParameters()
  672. {
  673. // Arrange
  674. var formContext = new FormContext();
  675. var viewContext = new Mock<ViewContext>();
  676. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  677. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  678. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  679. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  680. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  681. htmlHelper.ClientValidationRuleFactory = delegate
  682. {
  683. ModelClientValidationRule rule = new ModelClientValidationRule { ValidationType = "type", ErrorMessage = "error" };
  684. rule.ValidationParameters["foo"] = "bar";
  685. rule.ValidationParameters["baz"] = "biff";
  686. return new[] { rule };
  687. };
  688. // Act
  689. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  690. // Assert
  691. Assert.Equal("error", result["data-val-type"]);
  692. Assert.Equal("bar", result["data-val-type-foo"]);
  693. Assert.Equal("biff", result["data-val-type-baz"]);
  694. }
  695. [Fact]
  696. public void GetUnobtrusiveValidationAttributesWithTwoClientRules()
  697. {
  698. // Arrange
  699. var formContext = new FormContext();
  700. var viewContext = new Mock<ViewContext>();
  701. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  702. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  703. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  704. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  705. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  706. htmlHelper.ClientValidationRuleFactory = delegate
  707. {
  708. ModelClientValidationRule rule1 = new ModelClientValidationRule { ValidationType = "type", ErrorMessage = "error" };
  709. rule1.ValidationParameters["foo"] = "bar";
  710. rule1.ValidationParameters["baz"] = "biff";
  711. ModelClientValidationRule rule2 = new ModelClientValidationRule { ValidationType = "othertype", ErrorMessage = "othererror" };
  712. rule2.ValidationParameters["true3"] = "false4";
  713. return new[] { rule1, rule2 };
  714. };
  715. // Act
  716. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  717. // Assert
  718. Assert.Equal("error", result["data-val-type"]);
  719. Assert.Equal("bar", result["data-val-type-foo"]);
  720. Assert.Equal("biff", result["data-val-type-baz"]);
  721. Assert.Equal("othererror", result["data-val-othertype"]);
  722. Assert.Equal("false4", result["data-val-othertype-true3"]);
  723. }
  724. [Fact]
  725. public void GetUnobtrusiveValidationAttributesUsesShortNameForModelMetadataLookup()
  726. {
  727. // Arrange
  728. string passedName = null;
  729. var formContext = new FormContext();
  730. var viewContext = new Mock<ViewContext>();
  731. var viewData = new ViewDataDictionary();
  732. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  733. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  734. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  735. viewData.TemplateInfo.HtmlFieldPrefix = "Prefix";
  736. var viewDataContainer = MvcHelper.GetViewDataContainer(viewData);
  737. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  738. htmlHelper.ClientValidationRuleFactory = (name, _) =>
  739. {
  740. passedName = name;
  741. return Enumerable.Empty<ModelClientValidationRule>();
  742. };
  743. // Act
  744. htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  745. // Assert
  746. Assert.Equal("foobar", passedName);
  747. }
  748. [Fact]
  749. public void GetUnobtrusiveValidationAttributeUsesViewDataForModelMetadataLookup()
  750. {
  751. // Arrange
  752. var formContext = new FormContext();
  753. var viewContext = new Mock<ViewContext>();
  754. var viewData = new ViewDataDictionary<MyModel>();
  755. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  756. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  757. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  758. viewData.TemplateInfo.HtmlFieldPrefix = "Prefix";
  759. var viewDataContainer = MvcHelper.GetViewDataContainer(viewData);
  760. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  761. // Act
  762. IDictionary<string, object> result = htmlHelper.GetUnobtrusiveValidationAttributes("MyProperty");
  763. // Assert
  764. Assert.Equal(2, result.Count);
  765. Assert.Equal("true", result["data-val"]);
  766. Assert.Equal("My required message", result["data-val-required"]);
  767. }
  768. class MyModel
  769. {
  770. [Required(ErrorMessage = "My required message")]
  771. public object MyProperty { get; set; }
  772. }
  773. [Fact]
  774. public void GetUnobtrusiveValidationAttributesMarksRenderedFieldsWithFullName()
  775. {
  776. // Arrange
  777. var formContext = new FormContext();
  778. var viewContext = new Mock<ViewContext>();
  779. var viewData = new ViewDataDictionary();
  780. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  781. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  782. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  783. viewData.TemplateInfo.HtmlFieldPrefix = "Prefix";
  784. var viewDataContainer = MvcHelper.GetViewDataContainer(viewData);
  785. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  786. // Act
  787. htmlHelper.GetUnobtrusiveValidationAttributes("foobar");
  788. // Assert
  789. Assert.False(formContext.RenderedField("foobar"));
  790. Assert.True(formContext.RenderedField("Prefix.foobar"));
  791. }
  792. [Fact]
  793. public void GetUnobtrusiveValidationAttributesGuardClauses()
  794. {
  795. // Arrange
  796. var formContext = new FormContext();
  797. var viewContext = new Mock<ViewContext>();
  798. viewContext.SetupGet(vc => vc.FormContext).Returns(formContext);
  799. viewContext.SetupGet(vc => vc.ClientValidationEnabled).Returns(true);
  800. viewContext.SetupGet(vc => vc.UnobtrusiveJavaScriptEnabled).Returns(true);
  801. var viewDataContainer = MvcHelper.GetViewDataContainer(new ViewDataDictionary());
  802. var htmlHelper = new HtmlHelper(viewContext.Object, viewDataContainer);
  803. // Act & Assert
  804. AssertBadClientValidationRule(htmlHelper, "Validation type names in unobtrusive client validation rules cannot be empty. Client rule type: System.Web.Mvc.ModelClientValidationRule", new ModelClientValidationRule());
  805. AssertBadClientValidationRule(htmlHelper, "Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: \"OnlyLowerCase\", client rule type: System.Web.Mvc.ModelClientValidationRule", new ModelClientValidationRule { ValidationType = "OnlyLowerCase" });
  806. AssertBadClientValidationRule(htmlHelper, "Validation type names in unobtrusive client validation rules must consist of only lowercase letters. Invalid name: \"nonumb3rs\", client rule type: System.Web.Mvc.ModelClientValidationRule", new ModelClientValidationRule { ValidationType = "nonumb3rs" });
  807. AssertBadClientValidationRule(htmlHelper, "Validation type names in unobtrusive client validation rules must be unique. The following validation type was seen more than once: rule", new ModelClientValidationRule { ValidationType = "rule" }, new ModelClientValidationRule { ValidationType = "rule" });
  808. var emptyParamName = new ModelClientValidationRule { ValidationType = "type" };
  809. emptyParamName.ValidationParameters[""] = "foo";
  810. AssertBadClientValidationRule(htmlHelper, "Validation parameter names in unobtrusive client validation rules cannot be empty. Client rule type: System.Web.Mvc.ModelClientValidationRule", emptyParamName);
  811. var paramNameMixedCase = new ModelClientValidationRule { ValidationType = "type" };
  812. paramNameMixedCase.ValidationParameters["MixedCase"] = "foo";
  813. AssertBadClientValidationRule(htmlHelper, "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: MixedCase, client rule type: System.Web.Mvc.ModelClientValidationRule", paramNameMixedCase);
  814. var paramNameStartsWithNumber = new ModelClientValidationRule { ValidationType = "type" };
  815. paramNameStartsWithNumber.ValidationParameters["2112"] = "foo";
  816. AssertBadClientValidationRule(htmlHelper, "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: 2112, client rule type: System.Web.Mvc.ModelClientValidationRule", paramNameStartsWithNumber);
  817. }
  818. [Fact]
  819. public void RawReturnsWrapperMarkup()
  820. {
  821. // Arrange
  822. var viewContext = new Mock<ViewContext>().Object;
  823. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  824. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  825. string markup = "<b>bold</b>";
  826. // Act
  827. IHtmlString markupHtml = htmlHelper.Raw(markup);
  828. // Assert
  829. Assert.Equal("<b>bold</b>", markupHtml.ToString());
  830. Assert.Equal("<b>bold</b>", markupHtml.ToHtmlString());
  831. }
  832. [Fact]
  833. public void RawAllowsNullValue()
  834. {
  835. // Arrange
  836. var viewContext = new Mock<ViewContext>().Object;
  837. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  838. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  839. // Act
  840. IHtmlString markupHtml = htmlHelper.Raw(null);
  841. // Assert
  842. Assert.Equal(null, markupHtml.ToString());
  843. Assert.Equal(null, markupHtml.ToHtmlString());
  844. }
  845. [Fact]
  846. public void RawAllowsNullObjectValue()
  847. {
  848. // Arrange
  849. var viewContext = new Mock<ViewContext>().Object;
  850. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  851. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  852. // Act
  853. IHtmlString markupHtml = htmlHelper.Raw((object)null);
  854. // Assert
  855. Assert.Equal(null, markupHtml.ToString());
  856. Assert.Equal(null, markupHtml.ToHtmlString());
  857. }
  858. [Fact]
  859. public void RawAllowsEmptyValue()
  860. {
  861. // Arrange
  862. var viewContext = new Mock<ViewContext>().Object;
  863. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  864. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  865. // Act
  866. IHtmlString markupHtml = htmlHelper.Raw("");
  867. // Assert
  868. Assert.Equal("", markupHtml.ToString());
  869. Assert.Equal("", markupHtml.ToHtmlString());
  870. }
  871. [Fact]
  872. public void RawReturnsWrapperMarkupOfObject()
  873. {
  874. // Arrange
  875. var viewContext = new Mock<ViewContext>().Object;
  876. var viewDataContainer = new Mock<IViewDataContainer>().Object;
  877. var htmlHelper = new HtmlHelper(viewContext, viewDataContainer);
  878. ObjectWithWrapperMarkup obj = new ObjectWithWrapperMarkup();
  879. // Act
  880. IHtmlString markupHtml = htmlHelper.Raw(obj);
  881. // Assert
  882. Assert.Equal("<b>boldFromObject</b>", markupHtml.ToString());
  883. Assert.Equal("<b>boldFromObject</b>", markupHtml.ToHtmlString());
  884. }
  885. [Fact]
  886. public void EvalStringAndFormatValueWithNullValueReturnsEmptyString()
  887. {
  888. // Arrange
  889. var htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary());
  890. // Act & Assert
  891. Assert.Equal(String.Empty, htmlHelper.FormatValue(null, "-{0}-"));
  892. Assert.Equal(String.Empty, htmlHelper.EvalString("nonExistant"));
  893. Assert.Equal(String.Empty, htmlHelper.EvalString("nonExistant", "-{0}-"));
  894. }
  895. [Fact]
  896. public void EvalStringAndFormatValueUseCurrentCulture()
  897. {
  898. // Arrange
  899. DateTime dt = new DateTime(1900, 1, 1, 0, 0, 0);
  900. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary() { { "date", dt } });
  901. string expectedFormattedDate = "-1900/01/01 12:00:00 AM-";
  902. // Act && Assert
  903. using (ReplaceCulture("en-ZA", "en-US"))
  904. {
  905. Assert.Equal(expectedFormattedDate, htmlHelper.FormatValue(dt, "-{0}-"));
  906. Assert.Equal(expectedFormattedDate, htmlHelper.EvalString("date", "-{0}-"));
  907. }
  908. }
  909. [Fact]
  910. public void EvalStringAndFormatValueWithEmptyFormatConvertsValueToString()
  911. {
  912. // Arrange
  913. DateTime dt = new DateTime(1900, 1, 1, 0, 0, 0);
  914. HtmlHelper htmlHelper = MvcHelper.GetHtmlHelper(new ViewDataDictionary() { { "date", dt } });
  915. string expectedUnformattedDate = "1900/01/01 12:00:00 AM";
  916. // Act && Assert
  917. using (ReplaceCulture("en-ZA", "en-US"))
  918. {
  919. Assert.Equal(expectedUnformattedDate, htmlHelper.FormatValue(dt, String.Empty));
  920. Assert.Equal(expectedUnformattedDate, htmlHelper.EvalString("date", String.Empty));
  921. Assert.Equal(expectedUnformattedDate, htmlHelper.EvalString("date"));
  922. }
  923. }
  924. private class ObjectWithWrapperMarkup
  925. {
  926. public override string ToString()
  927. {
  928. return "<b>boldFromObject</b>";
  929. }
  930. }
  931. // Helpers
  932. private static void AssertBadClientValidationRule(HtmlHelper htmlHelper, string expectedMessage, params ModelClientValidationRule[] rules)
  933. {
  934. htmlHelper.ClientValidationRuleFactory = delegate { return rules; };
  935. Assert.Throws<InvalidOperationException>(
  936. () => htmlHelper.GetUnobtrusiveValidationAttributes(Guid.NewGuid().ToString()),
  937. expectedMessage
  938. );
  939. }
  940. internal static ValueProviderResult GetValueProviderResult(object rawValue, string attemptedValue)
  941. {
  942. return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.InvariantCulture);
  943. }
  944. internal static IDisposable ReplaceCulture(string currentCulture, string currentUICulture)
  945. {
  946. CultureInfo newCulture = CultureInfo.GetCultureInfo(currentCulture);
  947. CultureInfo newUICulture = CultureInfo.GetCultureInfo(currentUICulture);
  948. CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;
  949. CultureInfo originalUICulture = Thread.CurrentThread.CurrentUICulture;
  950. Thread.CurrentThread.CurrentCulture = newCulture;
  951. Thread.CurrentThread.CurrentUICulture = newUICulture;
  952. return new CultureReplacement { OriginalCulture = originalCulture, OriginalUICulture = originalUICulture };
  953. }
  954. private class CultureReplacement : IDisposable
  955. {
  956. public CultureInfo OriginalCulture;
  957. public CultureInfo OriginalUICulture;
  958. public void Dispose()
  959. {
  960. Thread.CurrentThread.CurrentCulture = OriginalCulture;
  961. Thread.CurrentThread.CurrentUICulture = OriginalUICulture;
  962. }
  963. }
  964. private class TestableHtmlHelper : HtmlHelper
  965. {
  966. TestableHtmlHelper(ViewContext viewContext, IViewDataContainer viewDataContainer)
  967. : base(viewContext, viewDataContainer)
  968. {
  969. }
  970. public static TestableHtmlHelper Create()
  971. {
  972. ViewDataDictionary viewData = new ViewDataDictionary();
  973. Mock<ViewContext> mockViewContext = new Mock<ViewContext>() { DefaultValue = DefaultValue.Mock };
  974. mockViewContext.Setup(c => c.HttpContext.Response.Output).Throws(new Exception("Response.Output should never be called."));
  975. mockViewContext.Setup(c => c.ViewData).Returns(viewData);
  976. mockViewContext.Setup(c => c.Writer).Returns(new StringWriter());
  977. Mock<IViewDataContainer> container = new Mock<IViewDataContainer>();
  978. container.Setup(c => c.ViewData).Returns(viewData);
  979. return new TestableHtmlHelper(mockViewContext.Object, container.Object);
  980. }
  981. public void RenderPartialInternal(string partialViewName,
  982. ViewDataDictionary viewData,
  983. object model,
  984. TextWriter writer,
  985. params IViewEngine[] engines)
  986. {
  987. base.RenderPartialInternal(partialViewName, viewData, model, writer, new ViewEngineCollection(engines));
  988. }
  989. }
  990. }
  991. }