From a83cbc00ef0415ab50844bca596eee917fd18a7d Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 12 Jan 2021 16:28:00 +1100 Subject: [PATCH] Adding tests for HijackedRouteEvaluator --- .../Routing/HijackedRouteEvaluatorTests.cs | 95 +++++++++++++++++++ .../Routing/HijackedRouteEvaluator.cs | 12 ++- 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/HijackedRouteEvaluatorTests.cs diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/HijackedRouteEvaluatorTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/HijackedRouteEvaluatorTests.cs new file mode 100644 index 0000000000..fecbe76d55 --- /dev/null +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/HijackedRouteEvaluatorTests.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.ViewEngines; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Primitives; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Extensions; +using Umbraco.Web; +using Umbraco.Web.Common.Controllers; +using Umbraco.Web.Website.Routing; + +namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Routing +{ + [TestFixture] + public class HijackedRouteEvaluatorTests + { + private class TestActionDescriptorCollectionProvider : ActionDescriptorCollectionProvider + { + private readonly IEnumerable _actions; + + public TestActionDescriptorCollectionProvider(IEnumerable actions) => _actions = actions; + + public override ActionDescriptorCollection ActionDescriptors => new ActionDescriptorCollection(_actions.ToList(), 1); + + public override IChangeToken GetChangeToken() => NullChangeToken.Singleton; + } + + private IActionDescriptorCollectionProvider GetActionDescriptors() => new TestActionDescriptorCollectionProvider( + new ActionDescriptor[] + { + new ControllerActionDescriptor + { + ActionName = "Index", + ControllerName = ControllerExtensions.GetControllerName(), + ControllerTypeInfo = typeof(RenderController).GetTypeInfo() + }, + new ControllerActionDescriptor + { + ActionName = "Index", + ControllerName = ControllerExtensions.GetControllerName(), + ControllerTypeInfo = typeof(Render1Controller).GetTypeInfo() + }, + new ControllerActionDescriptor + { + ActionName = "Index", + ControllerName = ControllerExtensions.GetControllerName(), + ControllerTypeInfo = typeof(Render2Controller).GetTypeInfo() + } + }); + + private class Render1Controller : ControllerBase, IRenderController + { + public IActionResult Index => Content("hello world"); + } + + private class Render2Controller : RenderController + { + public Render2Controller(ILogger logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor) + : base(logger, compositeViewEngine, umbracoContextAccessor) + { + } + } + + [TestCase("index", "Render", "Index", true)] + [TestCase("Index", "Render1", "Index", true)] + [TestCase("Index", "render2", "Index", true)] + [TestCase("NotFound", "Render", "Index", true)] + [TestCase("NotFound", "Render1", "Index", true)] + [TestCase("NotFound", "Render2", "Index", true)] + public void Matches_Controller(string action, string controller, string resultAction, bool matches) + { + var evaluator = new HijackedRouteEvaluator( + new NullLogger(), + GetActionDescriptors()); + + HijackedRouteResult result = evaluator.Evaluate(controller, action); + Assert.AreEqual(matches, result.Success); + if (matches) + { + Assert.IsTrue(result.ActionName.InvariantEquals(resultAction), "expected {0} does not match resulting action {1}", resultAction, result.ActionName); + Assert.IsTrue(result.ControllerName.InvariantEquals(controller), "expected {0} does not match resulting controller {1}", controller, result.ControllerName); + } + } + } +} diff --git a/src/Umbraco.Web.Website/Routing/HijackedRouteEvaluator.cs b/src/Umbraco.Web.Website/Routing/HijackedRouteEvaluator.cs index a72268d298..79036a01e1 100644 --- a/src/Umbraco.Web.Website/Routing/HijackedRouteEvaluator.cs +++ b/src/Umbraco.Web.Website/Routing/HijackedRouteEvaluator.cs @@ -50,14 +50,22 @@ namespace Umbraco.Web.Website.Routing && TypeHelper.IsTypeAssignableFrom(controllerDescriptor.ControllerTypeInfo)) { // now check if the custom action matches - var customActionExists = action != null && customControllerCandidates.Any(x => x.ActionName.InvariantEquals(action)); + var resultingAction = DefaultActionName; + if (action != null) + { + var found = customControllerCandidates.FirstOrDefault(x => x.ActionName.InvariantEquals(action))?.ActionName; + if (found != null) + { + resultingAction = found; + } + } // it's a hijacked route with a custom controller, so return the the values return new HijackedRouteResult( true, controllerDescriptor.ControllerName, controllerDescriptor.ControllerTypeInfo, - customActionExists ? action : DefaultActionName); + resultingAction); } else {