PageRenderTime 261ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/test/System.Web.WebPages.Test/WebPage/RenderPageTest.cs

https://bitbucket.org/mdavid/aspnetwebstack
C# | 866 lines | 584 code | 65 blank | 217 comment | 0 complexity | 8a0ef662613a1192f42cde9491644ee9 MD5 | raw file
  1. using System.Collections.Generic;
  2. using System.Globalization;
  3. using System.IO;
  4. using System.Web.WebPages.Resources;
  5. using Moq;
  6. using Xunit;
  7. using Assert = Microsoft.TestCommon.AssertEx;
  8. namespace System.Web.WebPages.Test
  9. {
  10. public class RenderPageTest
  11. {
  12. [Fact]
  13. public void RenderBasicTest()
  14. {
  15. // A simple page that does the following:
  16. // @{ PageData["Title"] = "MyPage"; }
  17. // @PageData["Title"]
  18. // hello world
  19. //
  20. // Expected rendered result is "MyPagehello world"
  21. var content = "hello world";
  22. var title = "MyPage";
  23. var result = Utils.RenderWebPage(
  24. p =>
  25. {
  26. p.PageData["Title"] = title;
  27. p.Write(p.PageData["Title"]);
  28. p.Write(content);
  29. });
  30. Assert.Equal(title + content, result);
  31. }
  32. [Fact]
  33. public void RenderDynamicDictionaryBasicTest()
  34. {
  35. // A simple page that does the following:
  36. // @{ Page.Title = "MyPage"; }
  37. // @Page.Title
  38. // hello world
  39. //
  40. // Expected rendered result is "MyPagehello world"
  41. var content = "hello world";
  42. var title = "MyPage";
  43. var result = Utils.RenderWebPage(
  44. p =>
  45. {
  46. p.Page.Title = title;
  47. p.Write(p.Page.Title);
  48. p.Write(content);
  49. });
  50. Assert.Equal(title + content, result);
  51. }
  52. [Fact]
  53. public void RenderPageBasicTest()
  54. {
  55. // ~/index.cshtml does the following:
  56. // hello
  57. // @RenderPage("subpage.cshtml")
  58. //
  59. // ~/subpage.cshtml does the following:
  60. // world
  61. //
  62. // Expected output is "helloworld"
  63. var result = Utils.RenderWebPageWithSubPage(
  64. p =>
  65. {
  66. p.Write("hello");
  67. p.Write(p.RenderPage("subpage.cshtml"));
  68. },
  69. p => { p.Write("world"); });
  70. Assert.Equal("helloworld", result);
  71. }
  72. [Fact]
  73. public void RenderPageAnonymousTypeTest()
  74. {
  75. // Test for passing an anonymous type object as an argument to RenderPage
  76. //
  77. // ~/index.cshtml does the following:
  78. // @RenderPage("subpage.cshtml", new { HelloKey = "hellovalue", MyKey = "myvalue" })
  79. //
  80. // ~/subpage.cshtml does the following:
  81. // @PageData["HelloKey"] @PageData["MyKey"] @Model.HelloKey @Model.MyKey
  82. //
  83. // Expected result: hellovalue myvalue hellovalue myvalue
  84. var result = Utils.RenderWebPageWithSubPage(
  85. p => { p.Write(p.RenderPage("subpage.cshtml", new { HelloKey = "hellovalue", MyKey = "myvalue" })); },
  86. p =>
  87. {
  88. p.Write(p.PageData["HelloKey"]);
  89. p.Write(" ");
  90. p.Write(p.PageData["MyKey"]);
  91. p.Write(" ");
  92. p.Write(p.Model.HelloKey);
  93. p.Write(" ");
  94. p.Write(p.Model.MyKey);
  95. });
  96. Assert.Equal("hellovalue myvalue hellovalue myvalue", result);
  97. }
  98. [Fact]
  99. public void RenderPageDynamicDictionaryAnonymousTypeTest()
  100. {
  101. // Test for passing an anonymous type object as an argument to RenderPage
  102. //
  103. // ~/index.cshtml does the following:
  104. // @RenderPage("subpage.cshtml", new { HelloKey = "hellovalue", MyKey = "myvalue" })
  105. //
  106. // ~/subpage.cshtml does the following:
  107. // @Page.HelloKey @Page.MyKey @Model.HelloKey @Model.MyKey
  108. //
  109. // Expected result: hellovalue myvalue hellovalue myvalue
  110. var result = Utils.RenderWebPageWithSubPage(
  111. p => { p.Write(p.RenderPage("subpage.cshtml", new { HelloKey = "hellovalue", MyKey = "myvalue" })); },
  112. p =>
  113. {
  114. p.Write(p.Page.HelloKey);
  115. p.Write(" ");
  116. p.Write(p.Page.MyKey);
  117. p.Write(" ");
  118. p.Write(p.Model.HelloKey);
  119. p.Write(" ");
  120. p.Write(p.Model.MyKey);
  121. });
  122. Assert.Equal("hellovalue myvalue hellovalue myvalue", result);
  123. }
  124. [Fact]
  125. public void RenderPageDictionaryTest()
  126. {
  127. // Test for passing a dictionary instance as an argument to RenderPage
  128. //
  129. // ~/index.cshtml does the following:
  130. // @RenderPage("subpage.cshtml", new Dictionary<string, object>(){ { "foo", 1 }, { "bar", "hello"} })
  131. //
  132. // ~/subpage.cshtml does the following:
  133. // @PageData["foo"] @PageData["bar"] @PageData[0]
  134. //
  135. // Expected result: 1 hello System.Collections.Generic.Dictionary`2[System.String,System.Object]
  136. var result = Utils.RenderWebPageWithSubPage(
  137. p => { p.Write(p.RenderPage("subpage.cshtml", new Dictionary<string, object>() { { "foo", 1 }, { "bar", "hello" } })); },
  138. p =>
  139. {
  140. p.Write(p.PageData["foo"]);
  141. p.Write(" ");
  142. p.Write(p.PageData["bar"]);
  143. p.Write(" ");
  144. p.Write(p.PageData[0]);
  145. });
  146. Assert.Equal("1 hello System.Collections.Generic.Dictionary`2[System.String,System.Object]", result);
  147. }
  148. [Fact]
  149. public void RenderPageDynamicDictionaryTest()
  150. {
  151. // Test for passing a dictionary instance as an argument to RenderPage
  152. //
  153. // ~/index.cshtml does the following:
  154. // @RenderPage("subpage.cshtml", new Dictionary<string, object>(){ { "foo", 1 }, { "bar", "hello"} })
  155. //
  156. // ~/subpage.cshtml does the following:
  157. // @Page.foo @Page.bar @Page[0]
  158. //
  159. // Expected result: 1 hello System.Collections.Generic.Dictionary`2[System.String,System.Object]
  160. var result = Utils.RenderWebPageWithSubPage(
  161. p => { p.Write(p.RenderPage("subpage.cshtml", new Dictionary<string, object>() { { "foo", 1 }, { "bar", "hello" } })); },
  162. p =>
  163. {
  164. p.Write(p.Page.foo);
  165. p.Write(" ");
  166. p.Write(p.Page.bar);
  167. p.Write(" ");
  168. p.Write(p.Page[0]);
  169. });
  170. Assert.Equal("1 hello System.Collections.Generic.Dictionary`2[System.String,System.Object]", result);
  171. }
  172. [Fact]
  173. public void RenderPageListTest()
  174. {
  175. // Test for passing a list of arguments to RenderPage
  176. //
  177. // ~/index.cshtml does the following:
  178. // @RenderPage("subpage.cshtml", "hello", "world", 1, 2, 3)
  179. //
  180. // ~/subpage.cshtml does the following:
  181. // @PageData[0] @PageData[1] @PageData[2] @PageData[3] @PageData[4]
  182. //
  183. // Expected result: hello world 1 2 3
  184. var result = Utils.RenderWebPageWithSubPage(
  185. p => { p.Write(p.RenderPage("subpage.cshtml", "hello", "world", 1, 2, 3)); },
  186. p =>
  187. {
  188. p.Write(p.PageData[0]);
  189. p.Write(" ");
  190. p.Write(p.PageData[1]);
  191. p.Write(" ");
  192. p.Write(p.PageData[2]);
  193. p.Write(" ");
  194. p.Write(p.PageData[3]);
  195. p.Write(" ");
  196. p.Write(p.PageData[4]);
  197. });
  198. Assert.Equal("hello world 1 2 3", result);
  199. }
  200. [Fact]
  201. public void RenderPageDynamicDictionaryListTest()
  202. {
  203. // Test for passing a list of arguments to RenderPage
  204. //
  205. // ~/index.cshtml does the following:
  206. // @RenderPage("subpage.cshtml", "hello", "world", 1, 2, 3)
  207. //
  208. // ~/subpage.cshtml does the following:
  209. // @Page[0] @Page[1] @Page[2] @Page[3] @Page[4]
  210. //
  211. // Expected result: hello world 1 2 3
  212. var result = Utils.RenderWebPageWithSubPage(
  213. p => { p.Write(p.RenderPage("subpage.cshtml", "hello", "world", 1, 2, 3)); },
  214. p =>
  215. {
  216. p.Write(p.Page[0]);
  217. p.Write(" ");
  218. p.Write(p.Page[1]);
  219. p.Write(" ");
  220. p.Write(p.Page[2]);
  221. p.Write(" ");
  222. p.Write(p.Page[3]);
  223. p.Write(" ");
  224. p.Write(p.Page[4]);
  225. });
  226. Assert.Equal("hello world 1 2 3", result);
  227. }
  228. private class Person
  229. {
  230. public string FirstName { get; set; }
  231. }
  232. [Fact]
  233. public void RenderPageDynamicValueTest()
  234. {
  235. // Test that PageData[key] returns a dynamic value.
  236. // ~/index.cshtml does the following:
  237. // @RenderPage("subpage.cshtml", new Person(){ FirstName="MyFirstName" })
  238. //
  239. // ~/subpage.cshtml does the following:
  240. // @PageData[0].FirstName
  241. //
  242. // Expected result: MyFirstName
  243. var result = Utils.RenderWebPageWithSubPage(
  244. p => { p.Write(p.RenderPage("subpage.cshtml", new Person() { FirstName = "MyFirstName" })); },
  245. p => { p.Write(p.PageData[0].FirstName); });
  246. Assert.Equal("MyFirstName", result);
  247. }
  248. [Fact]
  249. public void RenderPageDynamicDictionaryDynamicValueTest()
  250. {
  251. // Test that PageData[key] returns a dynamic value.
  252. // ~/index.cshtml does the following:
  253. // @RenderPage("subpage.cshtml", new Person(){ FirstName="MyFirstName" })
  254. //
  255. // ~/subpage.cshtml does the following:
  256. // @Page[0].FirstName
  257. //
  258. // Expected result: MyFirstName
  259. var result = Utils.RenderWebPageWithSubPage(
  260. p => { p.Write(p.RenderPage("subpage.cshtml", new Person() { FirstName = "MyFirstName" })); },
  261. p => { p.Write(p.Page[0].FirstName); });
  262. Assert.Equal("MyFirstName", result);
  263. }
  264. [Fact]
  265. public void PageDataSetByParentTest()
  266. {
  267. // Items set in the PageData should be accessible by the subpage
  268. var result = Utils.RenderWebPageWithSubPage(
  269. p =>
  270. {
  271. p.PageData["test"] = "hello";
  272. p.Write(p.RenderPage("subpage.cshtml"));
  273. },
  274. p => { p.Write(p.PageData["test"]); });
  275. Assert.Equal("hello", result);
  276. }
  277. [Fact]
  278. public void DynamicDictionarySetByParentTest()
  279. {
  280. // Items set in the PageData should be accessible by the subpage
  281. var result = Utils.RenderWebPageWithSubPage(
  282. p =>
  283. {
  284. p.Page.test = "hello";
  285. p.Write(p.RenderPage("subpage.cshtml"));
  286. },
  287. p => { p.Write(p.Page.test); });
  288. Assert.Equal("hello", result);
  289. }
  290. [Fact]
  291. public void OverridePageDataSetByParentTest()
  292. {
  293. // Items set in the PageData should be accessible by the subpage unless
  294. // overriden by parameters passed into RenderPage, in which case the
  295. // specified value should be used.
  296. var result = Utils.RenderWebPageWithSubPage(
  297. p =>
  298. {
  299. p.PageData["test"] = "hello";
  300. p.Write(p.RenderPage("subpage.cshtml", new { Test = "world" }));
  301. },
  302. p =>
  303. {
  304. p.Write(p.PageData["test"]);
  305. p.Write(p.PageData[0].Test);
  306. });
  307. Assert.Equal("worldworld", result);
  308. }
  309. [Fact]
  310. public void OverrideDynamicDictionarySetByParentTest()
  311. {
  312. // Items set in the PageData should be accessible by the subpage unless
  313. // overriden by parameters passed into RenderPage, in which case the
  314. // specified value should be used.
  315. var result = Utils.RenderWebPageWithSubPage(
  316. p =>
  317. {
  318. p.PageData["test"] = "hello";
  319. p.Write(p.RenderPage("subpage.cshtml", new { Test = "world" }));
  320. },
  321. p =>
  322. {
  323. p.Write(p.Page.test);
  324. p.Write(p.Page[0].Test);
  325. });
  326. Assert.Equal("worldworld", result);
  327. }
  328. [Fact]
  329. public void RenderPageMissingKeyTest()
  330. {
  331. // Test that using PageData with a missing key returns null
  332. //
  333. // ~/index.cshtml does the following:
  334. // @RenderPage("subpage.cshtml", new Dictionary<string, object>(){ { "foo", 1 }, { "bar", "hello"} })
  335. // @RenderPage("subpage.cshtml", "x", "y", "z")
  336. //
  337. // ~/subpage.cshtml does the following:
  338. // @(PageData[1] ?? "null")
  339. // @(PageData["bar"] ?? "null")
  340. //
  341. // Expected result: null hello y null
  342. var result = Utils.RenderWebPageWithSubPage(
  343. p =>
  344. {
  345. p.Write(p.RenderPage("subpage.cshtml", new Dictionary<string, object>() { { "foo", 1 }, { "bar", "hello" } }));
  346. p.Write(p.RenderPage("subpage.cshtml", "x", "y", "z"));
  347. },
  348. p =>
  349. {
  350. p.Write(p.PageData[1] ?? "null1");
  351. p.Write(" ");
  352. p.Write(p.PageData["bar"] ?? "null2");
  353. p.Write(" ");
  354. });
  355. Assert.Equal("null1 hello y null2 ", result);
  356. }
  357. [Fact]
  358. public void RenderPageDynamicDictionaryMissingKeyTest()
  359. {
  360. // Test that using PageData with a missing key returns null
  361. //
  362. // ~/index.cshtml does the following:
  363. // @RenderPage("subpage.cshtml", new Dictionary<string, object>(){ { "foo", 1 }, { "bar", "hello"} })
  364. // @RenderPage("subpage.cshtml", "x", "y", "z")
  365. //
  366. // ~/subpage.cshtml does the following:
  367. // @(Page[1] ?? "null")
  368. // @(Page.bar ?? "null")
  369. //
  370. // Expected result: null hello y null
  371. Action<WebPage> subPage = p =>
  372. {
  373. p.Write(p.Page[1] ?? "null1");
  374. p.Write(" ");
  375. p.Write(p.Page.bar ?? "null2");
  376. p.Write(" ");
  377. };
  378. var result = Utils.RenderWebPageWithSubPage(
  379. p => { p.Write(p.RenderPage("subpage.cshtml", new Dictionary<string, object>() { { "foo", 1 }, { "bar", "hello" } })); }, subPage);
  380. Assert.Equal("null1 hello ", result);
  381. result = Utils.RenderWebPageWithSubPage(
  382. p => { p.Write(p.RenderPage("subpage.cshtml", "x", "y", "z")); }, subPage);
  383. Assert.Equal("y null2 ", result);
  384. }
  385. [Fact]
  386. public void RenderPageNoArgumentsTest()
  387. {
  388. // Test that using PageData within the calling page, and also
  389. // within the subppage when the calling page doesn't provide any arguments
  390. //
  391. // ~/index.cshtml does the following:
  392. // @(PageData["foo"] ?? "null1")
  393. // @RenderPage("subpage.cshtml")
  394. //
  395. // ~/subpage.cshtml does the following:
  396. // @(PageData[1] ?? "null2")
  397. // @(PageData["bar"] ?? "null3")
  398. //
  399. // Expected result: null1 null2 null3
  400. var result = Utils.RenderWebPageWithSubPage(
  401. p =>
  402. {
  403. p.Write(p.PageData["foo"] ?? "null1 ");
  404. p.Write(p.RenderPage("subpage.cshtml"));
  405. },
  406. p =>
  407. {
  408. p.Write(p.PageData[1] ?? "null2");
  409. p.Write(" ");
  410. p.Write(p.PageData["bar"] ?? "null3");
  411. });
  412. Assert.Equal("null1 null2 null3", result);
  413. }
  414. [Fact]
  415. public void RenderPageDynamicDictionaryNoArgumentsTest()
  416. {
  417. // Test that using PageData within the calling page, and also
  418. // within the subppage when the calling page doesn't provide any arguments
  419. //
  420. // ~/index.cshtml does the following:
  421. // @(Page.foo ?? "null1")
  422. // @RenderPage("subpage.cshtml")
  423. //
  424. // ~/subpage.cshtml does the following:
  425. // @(Page[1] ?? "null2")
  426. // @(Page.bar ?? "null3")
  427. //
  428. // Expected result: null1 null2 null3
  429. var result = Utils.RenderWebPageWithSubPage(
  430. p =>
  431. {
  432. p.Write(p.Page.foo ?? "null1 ");
  433. p.Write(p.RenderPage("subpage.cshtml"));
  434. },
  435. p =>
  436. {
  437. p.Write(p.Page[1] ?? "null2");
  438. p.Write(" ");
  439. p.Write(p.Page.bar ?? "null3");
  440. });
  441. Assert.Equal("null1 null2 null3", result);
  442. }
  443. [Fact]
  444. public void RenderPageNestedSubPageListTest()
  445. {
  446. // Test that PageData for each level of nesting returns the values as specified in the
  447. // previous calling page.
  448. //
  449. // ~/index.cshtml does the following:
  450. // @(PageData["foo"] ?? "null")
  451. // @RenderPage("subpage1.cshtml", "a", "b", "c")
  452. //
  453. // ~/subpage1.cshtml does the following:
  454. // @(PageData[0] ?? "sub1null0")
  455. // @(PageData[1] ?? "sub1null1")
  456. // @(PageData[2] ?? "sub1null2")
  457. // @(PageData[3] ?? "sub1null3")
  458. // @RenderPage("subpage2.cshtml", "x", "y", "z")
  459. //
  460. // ~/subpage2.cshtml does the following:
  461. // @(PageData[0] ?? "sub2null0")
  462. // @(PageData[1] ?? "sub2null1")
  463. // @(PageData[2] ?? "sub2null2")
  464. // @(PageData[3] ?? "sub2null3")
  465. //
  466. // Expected result: null a b c sub1null3 x y z sub2null3
  467. var page = Utils.CreatePage(
  468. p =>
  469. {
  470. p.Write(p.PageData["foo"] ?? "null ");
  471. p.Write(p.RenderPage("subpage1.cshtml", "a", "b", "c"));
  472. });
  473. var subpage1Path = "~/subpage1.cshtml";
  474. var subpage1 = Utils.CreatePage(
  475. p =>
  476. {
  477. p.Write(p.PageData[0] ?? "sub1null0");
  478. p.Write(" ");
  479. p.Write(p.PageData[1] ?? "sub1null1");
  480. p.Write(" ");
  481. p.Write(p.PageData[2] ?? "sub1null2");
  482. p.Write(" ");
  483. p.Write(p.PageData[3] ?? "sub1null3");
  484. p.Write(" ");
  485. p.Write(p.RenderPage("subpage2.cshtml", "x", "y", "z"));
  486. }, subpage1Path);
  487. var subpage2Path = "~/subpage2.cshtml";
  488. var subpage2 = Utils.CreatePage(
  489. p =>
  490. {
  491. p.Write(p.PageData[0] ?? "sub2null0");
  492. p.Write(" ");
  493. p.Write(p.PageData[1] ?? "sub2null1");
  494. p.Write(" ");
  495. p.Write(p.PageData[2] ?? "sub2null2");
  496. p.Write(" ");
  497. p.Write(p.PageData[3] ?? "sub2null3");
  498. }, subpage2Path);
  499. Utils.AssignObjectFactoriesAndDisplayModeProvider(page, subpage1, subpage2);
  500. var result = Utils.RenderWebPage(page);
  501. Assert.Equal("null a b c sub1null3 x y z sub2null3", result);
  502. }
  503. [Fact]
  504. public void RenderPageNestedSubPageAnonymousTypeTest()
  505. {
  506. // Test that PageData for each level of nesting returns the values as specified in the
  507. // previous calling page.
  508. //
  509. // ~/index.cshtml does the following:
  510. // @(PageData["foo"] ?? "null")
  511. // @RenderPage("subpage.cshtml", new { foo = 1 , bar = "hello" })
  512. //
  513. // ~/subpage1.cshtml does the following:
  514. // @(PageData["foo"] ?? "sub1nullfoo")
  515. // @(PageData["bar"] ?? "sub1nullbar")
  516. // @(PageData["x"] ?? "sub1nullx")
  517. // @(PageData["y"] ?? "sub1nully")
  518. // @RenderPage("subpage2.cshtml", new { bar = "world", x = "good", y = "bye"})
  519. //
  520. // ~/subpage2.cshtml does the following:
  521. // @(PageData["foo"] ?? "sub2nullfoo")
  522. // @(PageData["bar"] ?? "sub2nullbar")
  523. // @(PageData["x"] ?? "sub2nullx")
  524. // @(PageData["y"] ?? "sub2nully")
  525. //
  526. // Expected result: null 1 hello sub1nullx sub1nully sub2nullfoo world good bye
  527. var page = Utils.CreatePage(
  528. p =>
  529. {
  530. p.Write(p.PageData["foo"] ?? "null ");
  531. p.Write(p.RenderPage("subpage1.cshtml", new { foo = 1, bar = "hello" }));
  532. });
  533. var subpage1Path = "~/subpage1.cshtml";
  534. var subpage1 = Utils.CreatePage(
  535. p =>
  536. {
  537. p.Write(p.PageData["foo"] ?? "sub1nullfoo");
  538. p.Write(" ");
  539. p.Write(p.PageData["bar"] ?? "sub1nullbar");
  540. p.Write(" ");
  541. p.Write(p.PageData["x"] ?? "sub1nullx");
  542. p.Write(" ");
  543. p.Write(p.PageData["y"] ?? "sub1nully");
  544. p.Write(" ");
  545. p.Write(p.RenderPage("subpage2.cshtml", new { bar = "world", x = "good", y = "bye" }));
  546. }, subpage1Path);
  547. var subpage2Path = "~/subpage2.cshtml";
  548. var subpage2 = Utils.CreatePage(
  549. p =>
  550. {
  551. p.Write(p.PageData["foo"] ?? "sub2nullfoo");
  552. p.Write(" ");
  553. p.Write(p.PageData["bar"] ?? "sub2nullbar");
  554. p.Write(" ");
  555. p.Write(p.PageData["x"] ?? "sub2nullx");
  556. p.Write(" ");
  557. p.Write(p.PageData["y"] ?? "sub2nully");
  558. }, subpage2Path);
  559. Utils.AssignObjectFactoriesAndDisplayModeProvider(subpage1, subpage2, page);
  560. var result = Utils.RenderWebPage(page);
  561. Assert.Equal("null 1 hello sub1nullx sub1nully sub2nullfoo world good bye", result);
  562. }
  563. [Fact]
  564. public void RenderPageNestedSubPageDictionaryTest()
  565. {
  566. // Test that PageData for each level of nesting returns the values as specified in the
  567. // previous calling page.
  568. //
  569. // ~/index.cshtml does the following:
  570. // @(PageData["foo"] ?? "null")
  571. // @RenderPage("subpage.cshtml", new Dictionary<string, object>(){ { "foo", 1 }, { "bar", "hello"} })
  572. //
  573. // ~/subpage1.cshtml does the following:
  574. // @(PageData["foo"] ?? "sub1nullfoo")
  575. // @(PageData["bar"] ?? "sub1nullbar")
  576. // @(PageData["x"] ?? "sub1nullx")
  577. // @(PageData["y"] ?? "sub1nully")
  578. // @RenderPage("subpage2.cshtml", new Dictionary<string, object>(){ { { "bar", "world"}, {"x", "good"}, {"y", "bye"} })
  579. //
  580. // ~/subpage2.cshtml does the following:
  581. // @(PageData["foo"] ?? "sub2nullfoo")
  582. // @(PageData["bar"] ?? "sub2nullbar")
  583. // @(PageData["x"] ?? "sub2nullx")
  584. // @(PageData["y"] ?? "sub2nully")
  585. //
  586. // Expected result: null 1 hello sub1nullx sub1nully sub2nullfoo world good bye
  587. var page = Utils.CreatePage(
  588. p =>
  589. {
  590. p.Write(p.PageData["foo"] ?? "null ");
  591. p.Write(p.RenderPage("subpage1.cshtml", new Dictionary<string, object>() { { "foo", 1 }, { "bar", "hello" } }));
  592. });
  593. var subpage1Path = "~/subpage1.cshtml";
  594. var subpage1 = Utils.CreatePage(
  595. p =>
  596. {
  597. p.Write(p.PageData["foo"] ?? "sub1nullfoo");
  598. p.Write(" ");
  599. p.Write(p.PageData["bar"] ?? "sub1nullbar");
  600. p.Write(" ");
  601. p.Write(p.PageData["x"] ?? "sub1nullx");
  602. p.Write(" ");
  603. p.Write(p.PageData["y"] ?? "sub1nully");
  604. p.Write(" ");
  605. p.Write(p.RenderPage("subpage2.cshtml", new Dictionary<string, object>() { { "bar", "world" }, { "x", "good" }, { "y", "bye" } }));
  606. }, subpage1Path);
  607. var subpage2Path = "~/subpage2.cshtml";
  608. var subpage2 = Utils.CreatePage(
  609. p =>
  610. {
  611. p.Write(p.PageData["foo"] ?? "sub2nullfoo");
  612. p.Write(" ");
  613. p.Write(p.PageData["bar"] ?? "sub2nullbar");
  614. p.Write(" ");
  615. p.Write(p.PageData["x"] ?? "sub2nullx");
  616. p.Write(" ");
  617. p.Write(p.PageData["y"] ?? "sub2nully");
  618. }, subpage2Path);
  619. Utils.AssignObjectFactoriesAndDisplayModeProvider(page, subpage1, subpage2);
  620. var result = Utils.RenderWebPage(page);
  621. Assert.Equal("null 1 hello sub1nullx sub1nully sub2nullfoo world good bye", result);
  622. }
  623. [Fact]
  624. public void RenderPageNestedParentPageDataTest()
  625. {
  626. // PageData should return values set by parent pages.
  627. var page = Utils.CreatePage(
  628. p =>
  629. {
  630. p.PageData["key1"] = "value1";
  631. p.Write(p.RenderPage("subpage1.cshtml"));
  632. });
  633. var subpage1Path = "~/subpage1.cshtml";
  634. var subpage1 = Utils.CreatePage(
  635. p =>
  636. {
  637. p.WriteLiteral("<subpage1>");
  638. p.Write(p.PageData["key1"]);
  639. p.Write(p.RenderPage("subpage2.cshtml"));
  640. p.Write(p.PageData["key1"]);
  641. p.PageData["key1"] = "value2";
  642. p.Write(p.RenderPage("subpage2.cshtml"));
  643. p.WriteLiteral("</subpage1>");
  644. }, subpage1Path);
  645. var subpage2Path = "~/subpage2.cshtml";
  646. var subpage2 = Utils.CreatePage(
  647. p =>
  648. {
  649. p.WriteLiteral("<subpage2>");
  650. p.Write(p.PageData["key1"]);
  651. // Setting the value in the child page should
  652. // not affect the parent page
  653. p.PageData["key1"] = "value3";
  654. p.Write(p.RenderPage("subpage3.cshtml", new { Key1 = "value4" }));
  655. p.WriteLiteral("</subpage2>");
  656. }, subpage2Path);
  657. var subpage3Path = "~/subpage3.cshtml";
  658. var subpage3 = Utils.CreatePage(
  659. p =>
  660. {
  661. p.WriteLiteral("<subpage3>");
  662. p.Write(p.PageData["key1"]);
  663. p.WriteLiteral("</subpage3>");
  664. }, subpage3Path);
  665. Utils.AssignObjectFactoriesAndDisplayModeProvider(subpage1, subpage2, subpage3, page);
  666. var result = Utils.RenderWebPage(page);
  667. Assert.Equal("<subpage1>value1<subpage2>value1<subpage3>value4</subpage3></subpage2>value1<subpage2>value2<subpage3>value4</subpage3></subpage2></subpage1>", result);
  668. }
  669. [Fact]
  670. public void WriteNullTest()
  671. {
  672. // Test for @null
  673. var result = Utils.RenderWebPage(
  674. p =>
  675. {
  676. p.Write(null);
  677. p.Write((object)null);
  678. p.Write((HelperResult)null);
  679. });
  680. Assert.Equal("", result);
  681. }
  682. [Fact]
  683. public void WriteTest()
  684. {
  685. // Test for calling WebPage.Write on text and HtmlHelper
  686. var text = "Hello";
  687. var wrote = false;
  688. Action<TextWriter> action = tw =>
  689. {
  690. tw.Write(text);
  691. wrote = true;
  692. };
  693. var helper = new HelperResult(action);
  694. var result = Utils.RenderWebPage(
  695. p => { p.Write(helper); });
  696. Assert.Equal(text, result);
  697. Assert.True(wrote);
  698. }
  699. [Fact]
  700. public void WriteLiteralTest()
  701. {
  702. // Test for calling WebPage.WriteLiteral on text and HtmlHelper
  703. var text = "Hello";
  704. var wrote = false;
  705. Action<TextWriter> action = tw =>
  706. {
  707. tw.Write(text);
  708. wrote = true;
  709. };
  710. var helper = new HelperResult(action);
  711. var result = Utils.RenderWebPage(
  712. p => { p.WriteLiteral(helper); });
  713. Assert.Equal(text, result);
  714. Assert.True(wrote);
  715. }
  716. [Fact]
  717. public void ExtensionNotSupportedTest()
  718. {
  719. // Tests that calling RenderPage on an unsupported extension returns a new simpler error message
  720. // instead of the full error about build providers in system.web.dll.
  721. var vpath = "~/hello/world.txt";
  722. var ext = ".txt";
  723. var compilationUtilThrowingBuildManager = new CompilationUtil();
  724. var otherExceptionBuildManager = new Mock<IVirtualPathFactory>();
  725. var msg = "The file \"~/hello/world.txt\" could not be rendered, because it does not exist or is not a valid page.";
  726. otherExceptionBuildManager.Setup(c => c.CreateInstance(It.IsAny<string>())).Throws(new HttpException(msg));
  727. Assert.Throws<HttpException>(() =>
  728. WebPage.CreateInstanceFromVirtualPath(vpath, new VirtualPathFactoryManager(compilationUtilThrowingBuildManager)),
  729. String.Format(CultureInfo.CurrentCulture, WebPageResources.WebPage_FileNotSupported, ext, vpath));
  730. // Test that other error messages are thrown unmodified.
  731. Assert.Throws<HttpException>(() => WebPage.CreateInstanceFromVirtualPath(vpath, otherExceptionBuildManager.Object), msg);
  732. }
  733. [Fact]
  734. public void RenderBodyCalledInChildPageTest()
  735. {
  736. // A Page that is called by RenderPage should not be able to call RenderBody().
  737. Assert.Throws<HttpException>(() =>
  738. Utils.RenderWebPageWithSubPage(
  739. p =>
  740. {
  741. p.Write("hello");
  742. p.Write(p.RenderPage("subpage.cshtml"));
  743. },
  744. p =>
  745. {
  746. p.Write("world");
  747. p.RenderBody();
  748. }),
  749. String.Format(CultureInfo.CurrentCulture, WebPageResources.WebPage_CannotRequestDirectly, "~/subpage.cshtml", "RenderBody"));
  750. }
  751. [Fact]
  752. public void RenderPageInvalidPageType()
  753. {
  754. var pagePath = "~/foo.js";
  755. var page = Utils.CreatePage(p => { p.Write(p.RenderPage(pagePath)); });
  756. var objectFactory = new Mock<IVirtualPathFactory>();
  757. objectFactory.Setup(c => c.Exists(It.IsAny<string>())).Returns<string>(p => pagePath.Equals(p, StringComparison.OrdinalIgnoreCase));
  758. objectFactory.Setup(c => c.CreateInstance(It.IsAny<string>())).Returns<string>(_ => null);
  759. page.VirtualPathFactory = objectFactory.Object;
  760. Assert.Throws<HttpException>(() =>
  761. {
  762. page.VirtualPathFactory = objectFactory.Object;
  763. page.DisplayModeProvider = new DisplayModeProvider();
  764. Utils.RenderWebPage(page);
  765. },
  766. String.Format(CultureInfo.CurrentCulture, WebPageResources.WebPage_InvalidPageType, pagePath));
  767. }
  768. [Fact]
  769. public void RenderPageValidPageType()
  770. {
  771. var pagePath = "~/foo.js";
  772. var page = Utils.CreatePage(p => { p.Write(p.RenderPage(pagePath)); });
  773. var contents = "hello world";
  774. var subPage = Utils.CreatePage(p => p.Write(contents), pagePath);
  775. Utils.AssignObjectFactoriesAndDisplayModeProvider(page, subPage);
  776. Assert.Equal(contents, Utils.RenderWebPage(page));
  777. }
  778. [Fact]
  779. public void RenderPageNull()
  780. {
  781. Assert.ThrowsArgumentNullOrEmptyString(() => Utils.RenderWebPage(p => p.RenderPage(null)), "path");
  782. }
  783. [Fact]
  784. public void RenderPageEmptyString()
  785. {
  786. Assert.ThrowsArgumentNullOrEmptyString(() => Utils.RenderWebPage(p => p.RenderPage("")), "path");
  787. }
  788. [Fact]
  789. public void SamePageCaseInsensitiveTest()
  790. {
  791. var result = Utils.RenderWebPage(
  792. p =>
  793. {
  794. p.PageData["xyz"] = "value";
  795. p.PageData["XYZ"] = "VALUE";
  796. p.Write(p.PageData["xYz"]);
  797. });
  798. Assert.Equal("VALUE", result);
  799. }
  800. }
  801. }