// Copyright (c) Umbraco. // See LICENSE for more details. using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Moq; using NUnit.Framework; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Web.Common.ModelBinders; using Umbraco.Cms.Web.Common.Views; namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Common.Views; [TestFixture] public class UmbracoViewPageTests { [Test] public void RenderModel_To_RenderModel() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelTestPage(); var viewData = GetViewDataDictionary(model); view.ViewData = viewData; Assert.AreSame(model, view.Model); } [Test] public void RenderModel_ContentType1_To_ContentType1() { var content = new ContentType1(null, Mock.Of()); var view = new ContentType1TestPage(); var viewData = GetViewDataDictionary(content); view.ViewData = viewData; Assert.IsInstanceOf(view.Model); } [Test] public void RenderModel_ContentType2_To_ContentType1() { var content = new ContentType2(null, Mock.Of()); var view = new ContentType1TestPage(); var viewData = GetViewDataDictionary(content); view.ViewData = viewData; Assert.IsInstanceOf(view.Model); } [Test] public void RenderModel_ContentType1_To_ContentType2() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new ContentType2TestPage(); var viewData = GetViewDataDictionary(model); Assert.Throws(() => view.SetViewData(viewData)); } [Test] public void RenderModel_ContentType1_To_RenderModelOf_ContentType1() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelOfContentType1TestPage(); var viewData = GetViewDataDictionary>(model); view.ViewData = viewData; Assert.IsInstanceOf>(view.Model); Assert.IsInstanceOf(view.Model.Content); } [Test] public void RenderModel_ContentType2_To_RenderModelOf_ContentType1() { var content = new ContentType2(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelOfContentType1TestPage(); var viewData = GetViewDataDictionary>(model); view.ViewData = viewData; Assert.IsInstanceOf>(view.Model); Assert.IsInstanceOf(view.Model.Content); } [Test] public void RenderModel_ContentType1_To_RenderModelOf_ContentType2() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelOfContentType2TestPage(); var viewData = GetViewDataDictionary(model); Assert.Throws(() => view.SetViewData(viewData)); } [Test] public void RenderModelOf_ContentType1_To_RenderModel() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelTestPage(); var viewData = GetViewDataDictionary(model); view.ViewData = viewData; Assert.AreSame(model, view.Model); } [Test] public void RenderModelOf_ContentType1_To_ContentType1() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new ContentType1TestPage(); var viewData = GetViewDataDictionary>(model); view.SetViewData(viewData); Assert.IsInstanceOf(view.Model); } [Test] public void RenderModelOf_ContentType2_To_ContentType1() { var content = new ContentType2(null, Mock.Of()); var model = new ContentModel(content); var view = new ContentType1TestPage(); var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model }; view.SetViewData(viewData); Assert.IsInstanceOf(view.Model); } [Test] public void RenderModelOf_ContentType1_To_ContentType2() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new ContentType2TestPage(); var viewData = GetViewDataDictionary(model); Assert.Throws(() => view.SetViewData(viewData)); } [Test] public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType1() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelOfContentType1TestPage(); var viewData = GetViewDataDictionary>(model); view.ViewData = viewData; Assert.IsInstanceOf>(view.Model); Assert.IsInstanceOf(view.Model.Content); } [Test] public void RenderModelOf_ContentType2_To_RenderModelOf_ContentType1() { var content = new ContentType2(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelOfContentType1TestPage(); var viewData = GetViewDataDictionary>(model); view.SetViewData(viewData); Assert.IsInstanceOf>(view.Model); Assert.IsInstanceOf(view.Model.Content); } [Test] public void RenderModelOf_ContentType1_To_RenderModelOf_ContentType2() { var content = new ContentType1(null, Mock.Of()); var model = new ContentModel(content); var view = new RenderModelOfContentType2TestPage(); var viewData = GetViewDataDictionary(model); Assert.Throws(() => view.SetViewData(viewData)); } [Test] public void ContentType1_To_RenderModel() { var content = new ContentType1(null, Mock.Of()); var view = new RenderModelTestPage(); var viewData = GetViewDataDictionary(content); view.SetViewData(viewData); Assert.IsInstanceOf(view.Model); } [Test] public void ContentType1_To_RenderModelOf_ContentType1() { var content = new ContentType1(null, Mock.Of()); var view = new RenderModelOfContentType1TestPage(); var viewData = GetViewDataDictionary(content); view.SetViewData(viewData); Assert.IsInstanceOf>(view.Model); Assert.IsInstanceOf(view.Model.Content); } [Test] public void ContentType2_To_RenderModelOf_ContentType1() { // Same as above but with ContentModel var content = new ContentType2(null, Mock.Of()); var view = new RenderModelOfContentType1TestPage(); var viewData = GetViewDataDictionary(content); view.SetViewData(viewData); Assert.IsInstanceOf>(view.Model); Assert.IsInstanceOf(view.Model.Content); } [Test] public void ContentType1_To_RenderModelOf_ContentType2() { var content = new ContentType1(null, Mock.Of()); var view = new RenderModelOfContentType2TestPage(); var viewData = GetViewDataDictionary(content); Assert.Throws(() => view.SetViewData(viewData)); } [Test] public void ContentType1_To_ContentType1() { var content = new ContentType1(null, Mock.Of()); var view = new ContentType1TestPage(); var viewData = GetViewDataDictionary(content); view.SetViewData(viewData); Assert.IsInstanceOf(view.Model); } [Test] public void ContentType1_To_ContentType2() { var content = new ContentType1(null, Mock.Of()); var view = new ContentType2TestPage(); var viewData = GetViewDataDictionary(content); Assert.Throws(() => view.SetViewData(viewData)); } [Test] public void ContentType2_To_ContentType1() { var content = new ContentType2(null, Mock.Of()); var view = new ContentType1TestPage(); var viewData = GetViewDataDictionary(content); view.SetViewData(viewData); Assert.IsInstanceOf(view.Model); } private ViewDataDictionary GetViewDataDictionary(object model) { var sourceViewDataDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); return new ViewDataDictionary(sourceViewDataDictionary, model); } private ViewDataDictionary GetViewDataDictionary(object model) { var sourceViewDataDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()); return new ViewDataDictionary(sourceViewDataDictionary) { Model = model }; } public class ContentType1 : PublishedContentWrapped { public ContentType1(IPublishedContent content, IPublishedValueFallback fallback) : base(content, fallback) { } } public class ContentType2 : ContentType1 { public ContentType2(IPublishedContent content, IPublishedValueFallback fallback) : base(content, fallback) { } } public class TestPage : UmbracoViewPage { private readonly ContentModelBinder _modelBinder = new(Mock.Of()); public override Task ExecuteAsync() => throw new NotImplementedException(); public void SetViewData(ViewDataDictionary viewData) => ViewData = (ViewDataDictionary)BindViewData(_modelBinder, viewData); } public class RenderModelTestPage : TestPage { } public class ContentType1TestPage : TestPage { } public class ContentType2TestPage : TestPage { } public class RenderModelOfContentType1TestPage : TestPage> { } public class RenderModelOfContentType2TestPage : TestPage> { } }