using System; using System.Linq; using System.Web.Mvc; using System.Web.Routing; using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Tests.TestHelpers; using Umbraco.Tests.TestHelpers.Stubs; using Umbraco.Web; using Umbraco.Web.Models; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using Umbraco.Core.Strings; using Umbraco.Core.Configuration; using Umbraco.Core.Dictionary; using Umbraco.Core.Hosting; using Umbraco.Core.IO; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.Services; using Umbraco.Tests.PublishedContent; using Umbraco.Tests.Testing; using Umbraco.Web.Runtime; using Current = Umbraco.Web.Composing.Current; using ILogger = Umbraco.Core.Logging.ILogger; using Umbraco.Tests.Common; namespace Umbraco.Tests.Routing { [TestFixture] [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerFixture)] public class RenderRouteHandlerTests : BaseWebTest { public override void SetUp() { base.SetUp(); WebInitialComponent.CreateRoutes( new TestUmbracoContextAccessor(), TestObjects.GetGlobalSettings(), ShortStringHelper, new SurfaceControllerTypeCollection(Enumerable.Empty()), new UmbracoApiControllerTypeCollection(Enumerable.Empty()), IOHelper); } public class TestRuntime : WebRuntime { public TestRuntime(Configs configs, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo) : base(configs, umbracoVersion, ioHelper, Mock.Of(), Mock.Of(), hostingEnvironment, backOfficeInfo, TestHelper.DbProviderFactoryCreator, TestHelper.MainDom, TestHelper.GetRequestCache(), new AspNetUmbracoBootPermissionChecker()) { } } protected override void Compose() { base.Compose(); // set the default RenderMvcController Current.DefaultRenderMvcControllerType = typeof(RenderMvcController); // FIXME: Wrong! var surfaceControllerTypes = new SurfaceControllerTypeCollection(Composition.TypeLoader.GetSurfaceControllers()); Composition.RegisterUnique(surfaceControllerTypes); var umbracoApiControllerTypes = new UmbracoApiControllerTypeCollection(Composition.TypeLoader.GetUmbracoApiControllers()); Composition.RegisterUnique(umbracoApiControllerTypes); Composition.RegisterUnique(_ => new DefaultShortStringHelper(TestHelpers.SettingsForTests.GenerateMockRequestHandlerSettings())); } public override void TearDown() { base.TearDown(); RouteTable.Routes.Clear(); } Template CreateTemplate(string alias) { var name = "Template"; var template = new Template(ShortStringHelper, name, alias); template.Content = ""; // else saving throws with a dirty internal error ServiceContext.FileService.SaveTemplate(template); return template; } /// /// Will route to the default controller and action since no custom controller is defined for this node route /// [Test] public void Umbraco_Route_Umbraco_Defined_Controller_Action() { var url = "~/dummy-page"; var template = CreateTemplate("homePage"); var route = RouteTable.Routes["Umbraco_default"]; var routeData = new RouteData { Route = route }; var umbracoContext = GetUmbracoContext(url, template.Id, routeData); var httpContext = GetHttpContextFactory(url, routeData).HttpContext; var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); frequest.PublishedContent = umbracoContext.Content.GetById(1174); frequest.TemplateModel = template; var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of()), ShortStringHelper); handler.GetHandlerForRoute(httpContext.Request.RequestContext, frequest); Assert.AreEqual("RenderMvc", routeData.Values["controller"].ToString()); //the route action will still be the one we've asked for because our RenderActionInvoker is the thing that decides // if the action matches. Assert.AreEqual("homePage", routeData.Values["action"].ToString()); } //test all template name styles to match the ActionName //[TestCase("home-\\234^^*32page")] // TODO: This fails! [TestCase("home-page")] [TestCase("home-page")] [TestCase("home-page")] [TestCase("Home-Page")] [TestCase("HomePage")] [TestCase("homePage")] [TestCase("site1/template2")] [TestCase("site1\\template2")] public void Umbraco_Route_User_Defined_Controller_Action(string templateName) { // NOTE - here we create templates with crazy aliases... assuming that these // could exist in the database... yet creating templates should sanitize // aliases one way or another... var url = "~/dummy-page"; var template = CreateTemplate(templateName); var route = RouteTable.Routes["Umbraco_default"]; var routeData = new RouteData() { Route = route }; var umbracoContext = GetUmbracoContext("~/dummy-page", template.Id, routeData, true); var httpContext = GetHttpContextFactory(url, routeData).HttpContext; var publishedRouter = CreatePublishedRouter(); var frequest = publishedRouter.CreateRequest(umbracoContext); frequest.PublishedContent = umbracoContext.Content.GetById(1172); frequest.TemplateModel = template; var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext); var type = new AutoPublishedContentType(22, "CustomDocument", new PublishedPropertyType[] { }); ContentTypesCache.GetPublishedContentTypeByAlias = alias => type; var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of(), context => { return new CustomDocumentController(Factory.GetInstance(), umbracoContextAccessor, Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance()); }), ShortStringHelper); handler.GetHandlerForRoute(httpContext.Request.RequestContext, frequest); Assert.AreEqual("CustomDocument", routeData.Values["controller"].ToString()); Assert.AreEqual( //global::umbraco.cms.helpers.Casing.SafeAlias(template.Alias), template.Alias.ToSafeAlias(ShortStringHelper), 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 CustomDocumentController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger) : base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger) { } public ActionResult HomePage(ContentModel model) { // ReSharper disable once Mvc.ViewNotResolved return View(); } } #endregion } }