diff --git a/src/Umbraco.Tests/DocumentLookups/BaseTest.cs b/src/Umbraco.Tests/DocumentLookups/BaseRoutingTest.cs
similarity index 76%
rename from src/Umbraco.Tests/DocumentLookups/BaseTest.cs
rename to src/Umbraco.Tests/DocumentLookups/BaseRoutingTest.cs
index f6b959b095..e43d502660 100644
--- a/src/Umbraco.Tests/DocumentLookups/BaseTest.cs
+++ b/src/Umbraco.Tests/DocumentLookups/BaseRoutingTest.cs
@@ -1,5 +1,6 @@
using System.Configuration;
using System.Linq;
+using System.Web.Routing;
using System.Xml;
using NUnit.Framework;
using Umbraco.Core;
@@ -15,7 +16,7 @@ using umbraco.cms.businesslogic.template;
namespace Umbraco.Tests.DocumentLookups
{
[TestFixture, RequiresSTA]
- public abstract class BaseTest
+ public abstract class BaseRoutingTest
{
[SetUp]
public virtual void Initialize()
@@ -23,6 +24,7 @@ namespace Umbraco.Tests.DocumentLookups
TestHelper.SetupLog4NetForTests();
TestHelper.InitializeDatabase();
Resolution.Freeze();
+ ApplicationContext = new ApplicationContext() { IsReady = true };
}
[TearDown]
@@ -36,9 +38,12 @@ namespace Umbraco.Tests.DocumentLookups
Cache.ClearAllCache();
}
- protected FakeHttpContextFactory GetHttpContextFactory(string url)
+ protected FakeHttpContextFactory GetHttpContextFactory(string url, RouteData routeData = null)
{
- var factory = new FakeHttpContextFactory(url);
+ var factory = routeData != null
+ ? new FakeHttpContextFactory(url, routeData)
+ : new FakeHttpContextFactory(url);
+
//set the state helper
StateHelper.HttpContext = factory.HttpContext;
@@ -46,19 +51,21 @@ namespace Umbraco.Tests.DocumentLookups
return factory;
}
- private UmbracoContext GetUmbracoContext(string url, Template template)
+ protected ApplicationContext ApplicationContext { get; private set; }
+
+ private UmbracoContext GetUmbracoContext(string url, Template template, RouteData routeData = null)
{
var ctx = new UmbracoContext(
- GetHttpContextFactory(url).HttpContext,
- new ApplicationContext(),
+ GetHttpContextFactory(url, routeData).HttpContext,
+ ApplicationContext,
new FakeRoutesCache());
SetupUmbracoContextForTest(ctx, template);
return ctx;
}
- protected RoutingContext GetRoutingContext(string url, Template template)
+ protected RoutingContext GetRoutingContext(string url, Template template, RouteData routeData = null)
{
- var umbracoContext = GetUmbracoContext(url, template);
+ var umbracoContext = GetUmbracoContext(url, template, routeData);
var contentStore = new XmlContentStore();
var niceUrls = new NiceUrlProvider(contentStore, umbracoContext);
var routingRequest = new RoutingContext(
@@ -70,23 +77,14 @@ namespace Umbraco.Tests.DocumentLookups
return routingRequest;
}
- ///
- /// Initlializes the UmbracoContext with specific XML
- ///
- ///
- ///
- protected void SetupUmbracoContextForTest(UmbracoContext umbracoContext, Template template)
+ protected virtual string GetXmlContent(Template template)
{
- umbracoContext.GetXmlDelegate = () =>
- {
- var xDoc = new XmlDocument();
-
- //create a custom xml structure to return
-
- xDoc.LoadXml(@"
+
-
+
+
]>
@@ -106,8 +104,24 @@ namespace Umbraco.Tests.DocumentLookups
-
-");
+
+";
+ }
+
+ ///
+ /// Initlializes the UmbracoContext with specific XML
+ ///
+ ///
+ ///
+ protected void SetupUmbracoContextForTest(UmbracoContext umbracoContext, Template template)
+ {
+ umbracoContext.GetXmlDelegate = () =>
+ {
+ var xDoc = new XmlDocument();
+
+ //create a custom xml structure to return
+
+ xDoc.LoadXml(GetXmlContent(template));
//return the custom x doc
return xDoc;
};
diff --git a/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs b/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs
index bd59149efc..fd331be25a 100644
--- a/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs
+++ b/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs
@@ -7,7 +7,7 @@ using umbraco.cms.businesslogic.template;
namespace Umbraco.Tests.DocumentLookups
{
[TestFixture]
- public class LookupByAliasTests : BaseTest
+ public class LookupByAliasTests : BaseRoutingTest
{
[TestCase("/this/is/my/alias", 1046)]
[TestCase("/anotheralias", 1046)]
diff --git a/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlTests.cs b/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlTests.cs
index 2ca7856754..7633b9d13e 100644
--- a/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlTests.cs
+++ b/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlTests.cs
@@ -8,7 +8,7 @@ using umbraco.cms.businesslogic.template;
namespace Umbraco.Tests.DocumentLookups
{
[TestFixture]
- public class LookupByNiceUrlTests : BaseTest
+ public class LookupByNiceUrlTests : BaseRoutingTest
{
[TestCase("/")]
diff --git a/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs
new file mode 100644
index 0000000000..0681556b3c
--- /dev/null
+++ b/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs
@@ -0,0 +1,94 @@
+using System.Linq;
+using System.Web.Mvc;
+using System.Web.Routing;
+using NUnit.Framework;
+using Umbraco.Core;
+using Umbraco.Tests.Stubs;
+using Umbraco.Tests.TestHelpers;
+using Umbraco.Web;
+using Umbraco.Web.Models;
+using Umbraco.Web.Mvc;
+using Umbraco.Web.Routing;
+using umbraco.BusinessLogic;
+using umbraco.cms.businesslogic.template;
+
+namespace Umbraco.Tests.DocumentLookups
+{
+ [TestFixture]
+ public class RenderRouteHandlerTests : BaseRoutingTest
+ {
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ var webBoot = new WebBootManager(new UmbracoApplication());
+ webBoot.CreateRoutes();
+ }
+
+ public override void TearDown()
+ {
+ base.TearDown();
+ RouteTable.Routes.Clear();
+ }
+
+ //test all template name styles to match the ActionName
+ [TestCase("home-page")]
+ [TestCase("Home-Page")]
+ [TestCase("HomePage")]
+ [TestCase("homePage")]
+ public void Umbraco_Route_User_Defined_Controller_Action(string templateName)
+ {
+ var template = Template.MakeNew(templateName, new User(0));
+ var route = RouteTable.Routes["Umbraco_default"];
+ var routeData = new RouteData() {Route = route};
+ var routingContext = GetRoutingContext("~/dummy-page", template, routeData);
+ var docRequest = new DocumentRequest(routingContext.UmbracoContext.UmbracoUrl, routingContext)
+ {
+ Node = routingContext.ContentStore.GetDocumentById(routingContext.UmbracoContext, 1172),
+ Template = template
+ };
+
+ var handler = new RenderRouteHandler(new TestControllerFactory());
+
+ handler.GetHandlerForRoute(routingContext.UmbracoContext.HttpContext.Request.RequestContext, docRequest);
+ Assert.AreEqual("CustomDocument", routeData.Values["controller"].ToString());
+ Assert.AreEqual("HomePage", routeData.Values["action"].ToString());
+ }
+
+
+ #region Internal classes
+
+ /////
+ ///// Used to test a user route (non-umbraco)
+ /////
+ //private class CustomUserController : Controller
+ //{
+
+ // public ActionResult Index()
+ // {
+ // return View();
+ // }
+
+ // public ActionResult Test(int id)
+ // {
+ // return View();
+ // }
+
+ //}
+
+ ///
+ /// Used to test a user route umbraco route
+ ///
+ public class CustomDocumentController : RenderMvcController
+ {
+
+ public ActionResult HomePage(RenderModel model)
+ {
+ return View();
+ }
+
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Umbraco.Tests/DocumentLookups/RouteTestExtensions.cs b/src/Umbraco.Tests/DocumentLookups/RouteTestExtensions.cs
new file mode 100644
index 0000000000..404e9ea4b2
--- /dev/null
+++ b/src/Umbraco.Tests/DocumentLookups/RouteTestExtensions.cs
@@ -0,0 +1,57 @@
+using System.Web;
+using System.Web.Routing;
+using Rhino.Mocks;
+using Umbraco.Tests.TestHelpers;
+
+namespace Umbraco.Tests.DocumentLookups
+{
+ public static class RouteTestExtensions
+ {
+
+ ///
+ /// Return the route data for the url based on a mocked context
+ ///
+ ///
+ ///
+ ///
+ public static RouteData GetDataForRoute(this RouteCollection routes, string requestUrl)
+ {
+ var context = new FakeHttpContextFactory(requestUrl);
+ return routes.GetDataForRoute(context.HttpContext);
+ }
+
+ ///
+ /// Get the route data based on the url and http context
+ ///
+ ///
+ ///
+ ///
+ public static RouteData GetDataForRoute(this RouteCollection routes, HttpContextBase httpContext)
+ {
+ var data = routes.GetRouteData(httpContext);
+
+ //set the route data on the request context
+ httpContext.Request.RequestContext.Stub(x => x.RouteData).Return(data);
+
+ return data;
+ }
+
+ ///
+ /// Checks if the URL will be ignored in the RouteTable
+ ///
+ ///
+ ///
+ ///
+ /// MVCContrib has a similar one but is faulty:
+ /// http://mvccontrib.codeplex.com/workitem/7173
+ ///
+ public static bool ShouldIgnoreRoute(this string url)
+ {
+ var http = new FakeHttpContextFactory(url);
+ var r = RouteTable.Routes.GetRouteData(http.HttpContext);
+ if (r == null) return false;
+ return (r.RouteHandler is StopRoutingHandler);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Stubs/TestControllerFactory.cs b/src/Umbraco.Tests/Stubs/TestControllerFactory.cs
new file mode 100644
index 0000000000..98bedaa078
--- /dev/null
+++ b/src/Umbraco.Tests/Stubs/TestControllerFactory.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Web.Mvc;
+using System.Web.Routing;
+using Umbraco.Core;
+
+namespace Umbraco.Tests.Stubs
+{
+ ///
+ /// Used in place of the UmbracoControllerFactory which relies on BuildManager which throws exceptions in a unit test context
+ ///
+ internal class TestControllerFactory : IControllerFactory
+ {
+
+ public IController CreateController(RequestContext requestContext, string controllerName)
+ {
+ var types = TypeFinder.FindClassesOfType(new[] { Assembly.GetExecutingAssembly() });
+
+ var controllerTypes = types.Where(x => x.Name.Equals(controllerName + "Controller", StringComparison.InvariantCultureIgnoreCase));
+ var t = controllerTypes.SingleOrDefault();
+
+ if (t == null)
+ return null;
+
+ return Activator.CreateInstance(t) as IController;
+ }
+
+ public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void ReleaseController(IController controller)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index e8b99d7221..51599750d7 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -60,9 +60,12 @@
-
+
+
+
+
diff --git a/src/Umbraco.Web/Routing/DocumentRequest.cs b/src/Umbraco.Web/Routing/DocumentRequest.cs
index 916f657cbe..8b125b9c2e 100644
--- a/src/Umbraco.Web/Routing/DocumentRequest.cs
+++ b/src/Umbraco.Web/Routing/DocumentRequest.cs
@@ -78,19 +78,7 @@ namespace Umbraco.Web.Routing
// to allow for fallbacks when doing dictionnary lookup and such?
public IDocument Node
- {
- //get
- //{
- // if (!HasNode)
- // return null;
- // if (_node == null)
- // {
- // //TODO: See the note below, if we don't allow for a get/set INode then how would someone implement
- // // their own INode? it would not be possible since we're instantiating a specific Node object here.
- // _node = new Node(XmlNode);
- // }
- // return _node;
- //}
+ {
get { return _node; }
set
{
@@ -100,27 +88,6 @@ namespace Umbraco.Web.Routing
}
}
- ////TODO: Should we remove this somehow in place of an INode getter/setter? we are really bound to the xml structure here
- /////
- ///// Gets or sets the document request's document xml node.
- /////
- //internal XmlNode XmlNode
- //{
- // get
- // {
- // return _xmlNode;
- // }
- // set
- // {
- // _xmlNode = value;
- // this.Template = null;
- // if (_xmlNode != null)
- // _nodeId = int.Parse(RoutingContext.ContentStore.GetNodeProperty(_xmlNode, "@id"));
- // else
- // _nodeId = 0;
- // }
- //}
-
///
/// Gets or sets the document request's template.
///
diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs
index 57a9308f5d..56a36232c9 100644
--- a/src/Umbraco.Web/WebBootManager.cs
+++ b/src/Umbraco.Web/WebBootManager.cs
@@ -51,12 +51,7 @@ namespace Umbraco.Web
ModelBinders.Binders.Add(new KeyValuePair(typeof(RenderModel), new RenderModelBinder()));
//set routes
- var route = RouteTable.Routes.MapRoute(
- "Umbraco_default",
- "Umbraco/RenderMvc/{action}/{id}",
- new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
- );
- route.RouteHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory());
+ CreateRoutes();
//find and initialize the application startup handlers, we need to initialize this resolver here because
//it is a special resolver where they need to be instantiated first before any other resolvers in order to bind to
@@ -107,6 +102,20 @@ namespace Umbraco.Web
return this;
}
+ ///
+ /// Creates the routes
+ ///
+ protected internal void CreateRoutes()
+ {
+ //set routes
+ var route = RouteTable.Routes.MapRoute(
+ "Umbraco_default",
+ "Umbraco/RenderMvc/{action}/{id}",
+ new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
+ );
+ route.RouteHandler = new RenderRouteHandler(ControllerBuilder.Current.GetControllerFactory());
+ }
+
///
/// Initializes all web based and core resolves
///