From c3747d70ceec8fa19cb9b61d0f3e008d3a669862 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Mon, 3 Sep 2012 07:54:09 +0700 Subject: [PATCH] Added ObjectExtensionsTests, Added functionality for MVC to render any macro types (i.e. razor and xslt, etc..) Adds UmbracoHelper as a property to the RenderViewPage for MVC. Tested rendering Xslt and Razor macros with and without parameters and works well. Next we need to get the RTE rendering with macros embedded in MVC. --- src/Umbraco.Tests/ObjectExtensionsTests.cs | 98 ++++++++++++++++++++++ src/Umbraco.Tests/StringExtensionsTests.cs | 7 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + src/Umbraco.Web/FormlessPage.cs | 20 +++++ src/Umbraco.Web/Mvc/RenderViewPage.cs | 14 ++-- src/Umbraco.Web/Umbraco.Web.csproj | 4 + src/Umbraco.Web/UmbracoHelper.cs | 72 ++++++++++++++++ 7 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 src/Umbraco.Tests/ObjectExtensionsTests.cs create mode 100644 src/Umbraco.Web/FormlessPage.cs create mode 100644 src/Umbraco.Web/UmbracoHelper.cs diff --git a/src/Umbraco.Tests/ObjectExtensionsTests.cs b/src/Umbraco.Tests/ObjectExtensionsTests.cs new file mode 100644 index 0000000000..022a84e144 --- /dev/null +++ b/src/Umbraco.Tests/ObjectExtensionsTests.cs @@ -0,0 +1,98 @@ +using System.Collections.Generic; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Tests.PartialTrust; +using Umbraco.Tests.TestHelpers; + +namespace Umbraco.Tests +{ + [TestFixture] + public class ObjectExtensionsTests : AbstractPartialTrustFixture + { + protected override void FixtureSetup() + { + base.FixtureSetup(); + TestHelper.SetupLog4NetForTests(); + } + + [Test] + public void ObjectExtensions_Object_To_Dictionary() + { + //Arrange + + var obj = new { Key1 = "value1", Key2 = "value2", Key3 = "value3" }; + + //Act + + var d = obj.ToDictionary(); + + //Assert + + Assert.IsTrue(d.Keys.Contains("Key1")); + Assert.IsTrue(d.Keys.Contains("Key2")); + Assert.IsTrue(d.Keys.Contains("Key3")); + Assert.AreEqual(d["Key1"], "value1"); + Assert.AreEqual(d["Key2"], "value2"); + Assert.AreEqual(d["Key3"], "value3"); + } + + [Test] + [TestOnlyInFullTrust] + public void CanConvertIntToNullableInt() + { + var i = 1; + var result = i.TryConvertTo(); + Assert.That(result.Success, Is.True); + } + + [Test] + [TestOnlyInFullTrust] + public void CanConvertNullableIntToInt() + { + int? i = 1; + var result = i.TryConvertTo(); + Assert.That(result.Success, Is.True); + } + + [Test] + [TestOnlyInFullTrust] + public virtual void CanConvertStringToBool() + { + var testCases = new Dictionary + { + {"TRUE", true}, + {"True", true}, + {"true", true}, + {"1", true}, + {"FALSE", false}, + {"False", false}, + {"false", false}, + {"0", false} + }; + + foreach (var testCase in testCases) + { + var result = testCase.Key.TryConvertTo(); + + Assert.IsTrue(result.Success); + Assert.AreEqual(testCase.Value, result.Result); + } + } + + /// + /// Run once before each test in derived test fixtures. + /// + public override void TestSetup() + { + return; + } + + /// + /// Run once after each test in derived test fixtures. + /// + public override void TestTearDown() + { + return; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/StringExtensionsTests.cs b/src/Umbraco.Tests/StringExtensionsTests.cs index de2499ba5f..73e828ac73 100644 --- a/src/Umbraco.Tests/StringExtensionsTests.cs +++ b/src/Umbraco.Tests/StringExtensionsTests.cs @@ -1,11 +1,14 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Security; using System.Text; +using System.Web.Mvc; using NUnit.Framework; using Umbraco.Core; namespace Umbraco.Tests { - [TestFixture] + [TestFixture] public class StringExtensionsTests { [TestCase("Hello this is my string", " string", "Hello this is my")] diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 30300c8f4c..7fd395f34f 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -62,6 +62,7 @@ + diff --git a/src/Umbraco.Web/FormlessPage.cs b/src/Umbraco.Web/FormlessPage.cs new file mode 100644 index 0000000000..6c7a309a9b --- /dev/null +++ b/src/Umbraco.Web/FormlessPage.cs @@ -0,0 +1,20 @@ +using System.Web.UI; + +namespace Umbraco.Web +{ + /// + /// A formless page for use with the rendering a control in a page via Server.Execute. + /// This ignores the check to check for a form control on the page. + /// + /// + /// UmbracoHelper currently uses this for rendering macros but could be used anywhere we want when rendering + /// a page with Server.Execute. + /// SD: I have a custom MVC engine that uses this in my own internal libs if we want to pull it out which is called ViewManager + /// and works really well for things like this. + /// + internal class FormlessPage : Page + { + public override void VerifyRenderingInServerForm(Control control) { } + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/RenderViewPage.cs b/src/Umbraco.Web/Mvc/RenderViewPage.cs index 3dff08149f..6362340605 100644 --- a/src/Umbraco.Web/Mvc/RenderViewPage.cs +++ b/src/Umbraco.Web/Mvc/RenderViewPage.cs @@ -68,11 +68,15 @@ namespace Umbraco.Web.Mvc return _cultureDictionary[key]; } - //private RazorLibraryCore _library; - //public RazorLibraryCore Library - //{ - // get { return _library ?? (_library = new RazorLibraryCore(Model.CurrentNode)); } - //} + private UmbracoHelper _helper; + + /// + /// Gets an UmbracoHelper + /// + public UmbracoHelper UmbracoHelper + { + get { return _helper ?? (_helper = new UmbracoHelper(UmbracoContext)); } + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index afce11d153..66d02003ac 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -243,6 +243,9 @@ + + ASPXCodeBehind + @@ -250,6 +253,7 @@ + diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs new file mode 100644 index 0000000000..8262ddfe48 --- /dev/null +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections; +using System.IO; +using System.Web; +using Umbraco.Core; +using umbraco; + +namespace Umbraco.Web +{ + /// + /// A helper class that provides many useful methods and functionality for using Umbraco in templates + /// + public class UmbracoHelper + { + private readonly UmbracoContext _umbracoContext; + + internal UmbracoHelper(UmbracoContext umbracoContext) + { + _umbracoContext = umbracoContext; + } + + + #region RenderMacro + + /// + /// Renders the macro with the specified alias. + /// + /// The alias. + /// + public IHtmlString RenderMacro(string alias) + { + return RenderMacro(alias, new { }); + } + + /// + /// Renders the macro with the specified alias, passing in the specified parameters. + /// + /// The alias. + /// The parameters. + /// + public IHtmlString RenderMacro(string alias, object parameters) + { + if (alias == null) throw new ArgumentNullException("alias"); + var containerPage = new FormlessPage(); + var m = macro.GetMacro(alias); + if (_umbracoContext.PageId == null) + { + throw new InvalidOperationException("Cannot render a macro when UmbracoContext.PageId is null."); + } + if (_umbracoContext.DocumentRequest == null) + { + throw new InvalidOperationException("Cannot render a macro when there is no current DocumentRequest."); + } + var macroProps = new Hashtable(); + foreach(var i in parameters.ToDictionary()) + { + //TODO: We are doing at ToLower here because for some insane reason the UpdateMacroModel method of macro.cs + // looks for a lower case match. WTF. the whole macro concept needs to be rewritten. + macroProps.Add(i.Key.ToLower(), i.Value); + } + var macroControl = m.renderMacro(macroProps, + UmbracoContext.Current.DocumentRequest.UmbracoPage.Elements, + _umbracoContext.PageId.Value); + containerPage.Controls.Add(macroControl); + var output = new StringWriter(); + _umbracoContext.HttpContext.Server.Execute(containerPage, output, false); + return new HtmlString(output.ToString()); + } + + #endregion + } +}