// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.IO; using System.Web.UI; using Moq; using Xunit; using Assert = Microsoft.TestCommon.AssertEx; namespace System.Web.Mvc.Test { public class ViewPageTest { [Fact] public void ModelProperty() { // Arrange object model = new object(); ViewDataDictionary viewData = new ViewDataDictionary(model); ViewPage viewPage = new ViewPage(); viewPage.ViewData = viewData; // Act object viewPageModel = viewPage.Model; // Assert Assert.Equal(model, viewPageModel); Assert.Equal(model, viewPage.ViewData.Model); } [Fact] public void ModelPropertyStronglyTypedViewPage() { // Arrange FooModel model = new FooModel(); ViewDataDictionary viewData = new ViewDataDictionary(model); ViewPage viewPage = new ViewPage(); viewPage.ViewData = viewData; // Act object viewPageModelObject = ((ViewPage)viewPage).Model; FooModel viewPageModelPerson = viewPage.Model; // Assert Assert.Equal(model, viewPageModelObject); Assert.Equal(model, viewPageModelPerson); } [Fact] public void SetViewItemOnBaseClassPropagatesToDerivedClass() { // Arrange ViewPage vpInt = new ViewPage(); ViewPage vp = vpInt; object o = new object(); // Act vp.ViewData.Model = o; // Assert Assert.Equal(o, vpInt.ViewData.Model); Assert.Equal(o, vp.ViewData.Model); } [Fact] public void SetViewItemOnDerivedClassPropagatesToBaseClass() { // Arrange ViewPage vpInt = new ViewPage(); ViewPage vp = vpInt; object o = new object(); // Act vpInt.ViewData.Model = o; // Assert Assert.Equal(o, vpInt.ViewData.Model); Assert.Equal(o, vp.ViewData.Model); } [Fact] public void SetViewItemToWrongTypeThrows() { // Arrange ViewPage vp = new ViewPage(); // Act & Assert Assert.Throws( delegate { vp.ViewData.Model = 50; }, "The model item passed into the dictionary is of type 'System.Int32', but this dictionary requires a model item of type 'System.String'."); } [Fact] public void RenderInitsHelpersAndSetsID() { // Arrange ViewPageWithNoProcessRequest viewPage = new ViewPageWithNoProcessRequest(); TextWriter writer = new StringWriter(); Mock mockViewContext = new Mock(); mockViewContext.Setup(c => c.Writer).Returns(writer); mockViewContext.Setup(c => c.HttpContext.Response.Output).Returns(TextWriter.Null); mockViewContext.Setup(c => c.HttpContext.Server.Execute(It.IsAny(), It.IsAny(), true)) .Callback((_h, _w, _pf) => { ViewPage.SwitchWriter switchWriter = _w as ViewPage.SwitchWriter; Assert.NotNull(switchWriter); Assert.Same(writer, switchWriter.InnerWriter); }) .Verifiable(); // Act viewPage.RenderView(mockViewContext.Object); // Assert mockViewContext.Verify(); Assert.NotNull(viewPage.Ajax); Assert.NotNull(viewPage.Html); Assert.NotNull(viewPage.Url); } [Fact] public void GenericPageRenderInitsHelpersAndSetsID() { // Arrange Mock mockViewContext = new Mock(); mockViewContext.Setup(c => c.Writer).Returns(new StringWriter()); mockViewContext.Setup(c => c.HttpContext.Response.Output).Returns(TextWriter.Null); mockViewContext.Setup(c => c.HttpContext.Server).Returns(new Mock().Object); ViewPageWithNoProcessRequest viewPage = new ViewPageWithNoProcessRequest(); // Act viewPage.RenderView(mockViewContext.Object); // Assert Assert.NotNull(viewPage.Ajax); Assert.NotNull(viewPage.Html); Assert.NotNull(viewPage.Url); Assert.NotNull(((ViewPage)viewPage).Html); Assert.NotNull(((ViewPage)viewPage).Url); } private static void WriterSetCorrectlyInternal(bool throwException) { // Arrange bool triggered = false; HtmlTextWriter writer = new HtmlTextWriter(TextWriter.Null); MockViewPage vp = new MockViewPage(); vp.RenderCallback = delegate() { triggered = true; Assert.Equal(writer, vp.Writer); if (throwException) { throw new CallbackException(); } }; // Act & Assert Assert.Null(vp.Writer); try { vp.RenderControl(writer); } catch (CallbackException) { } Assert.Null(vp.Writer); Assert.True(triggered); } [Fact] public void WriterSetCorrectly() { WriterSetCorrectlyInternal(false /* throwException */); } [Fact] public void WriterSetCorrectlyThrowException() { WriterSetCorrectlyInternal(true /* throwException */); } private sealed class ViewPageWithNoProcessRequest : ViewPage { public override void ProcessRequest(HttpContext context) { } } private sealed class ViewPageWithNoProcessRequest : ViewPage { public override void ProcessRequest(HttpContext context) { } } [Fact] public void ViewBagProperty_ReflectsViewData() { // Arrange ViewPage page = new ViewPage(); page.ViewData["A"] = 1; // Act & Assert Assert.NotNull(page.ViewBag); Assert.Equal(1, page.ViewBag.A); } [Fact] public void ViewBagProperty_ReflectsNewViewDataInstance() { // Arrange ViewPage page = new ViewPage(); page.ViewData["A"] = 1; page.ViewData = new ViewDataDictionary() { { "A", "bar" } }; // Act & Assert Assert.Equal("bar", page.ViewBag.A); } [Fact] public void ViewBagProperty_PropagatesChangesToViewData() { // Arrange ViewPage page = new ViewPage(); page.ViewData["A"] = 1; // Act page.ViewBag.A = "foo"; page.ViewBag.B = 2; // Assert Assert.Equal("foo", page.ViewData["A"]); Assert.Equal(2, page.ViewData["B"]); } private sealed class MockViewPage : ViewPage { public MockViewPage() { } public Action RenderCallback { get; set; } protected override void RenderChildren(HtmlTextWriter writer) { if (RenderCallback != null) { RenderCallback(); } base.RenderChildren(writer); } } private sealed class FooModel { } private sealed class CallbackException : Exception { } } }