2021-01-13 11:08:48 +11:00
|
|
|
using System;
|
2021-02-04 13:09:28 +11:00
|
|
|
using System.Reflection;
|
2021-01-13 11:08:48 +11:00
|
|
|
using System.Threading.Tasks;
|
2021-02-03 15:47:27 +11:00
|
|
|
using Microsoft.AspNetCore.DataProtection;
|
2021-01-13 11:08:48 +11:00
|
|
|
using Microsoft.AspNetCore.Http;
|
2021-02-04 13:09:28 +11:00
|
|
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
2021-01-13 11:08:48 +11:00
|
|
|
using Microsoft.AspNetCore.Mvc.ViewEngines;
|
|
|
|
|
using Microsoft.AspNetCore.Routing;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Moq;
|
|
|
|
|
using NUnit.Framework;
|
2021-02-18 11:06:02 +01:00
|
|
|
using Umbraco.Cms.Core;
|
|
|
|
|
using Umbraco.Cms.Core.Configuration.Models;
|
2021-03-01 14:20:15 +11:00
|
|
|
using Umbraco.Cms.Core.Events;
|
2021-09-17 12:47:41 -06:00
|
|
|
using Umbraco.Cms.Core.Models.PublishedContent;
|
2021-02-18 11:06:02 +01:00
|
|
|
using Umbraco.Cms.Core.PublishedCache;
|
|
|
|
|
using Umbraco.Cms.Core.Routing;
|
|
|
|
|
using Umbraco.Cms.Core.Services;
|
|
|
|
|
using Umbraco.Cms.Core.Web;
|
|
|
|
|
using Umbraco.Cms.Tests.UnitTests.TestHelpers;
|
|
|
|
|
using Umbraco.Cms.Web.Common.Controllers;
|
|
|
|
|
using Umbraco.Cms.Web.Common.Routing;
|
|
|
|
|
using Umbraco.Cms.Web.Website.Controllers;
|
|
|
|
|
using Umbraco.Cms.Web.Website.Routing;
|
2021-01-13 11:08:48 +11:00
|
|
|
using Umbraco.Extensions;
|
2021-02-18 11:06:02 +01:00
|
|
|
using static Umbraco.Cms.Core.Constants.Web.Routing;
|
2021-01-13 11:08:48 +11:00
|
|
|
|
2021-02-18 11:06:02 +01:00
|
|
|
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Website.Routing
|
2021-01-13 11:08:48 +11:00
|
|
|
{
|
|
|
|
|
[TestFixture]
|
|
|
|
|
public class UmbracoRouteValueTransformerTests
|
|
|
|
|
{
|
|
|
|
|
private IOptions<GlobalSettings> GetGlobalSettings() => Options.Create(new GlobalSettings());
|
|
|
|
|
|
|
|
|
|
private UmbracoRouteValueTransformer GetTransformerWithRunState(
|
|
|
|
|
IUmbracoContextAccessor ctx,
|
|
|
|
|
IRoutableDocumentFilter filter = null,
|
|
|
|
|
IPublishedRouter router = null,
|
|
|
|
|
IUmbracoRouteValuesFactory routeValuesFactory = null)
|
|
|
|
|
=> GetTransformer(ctx, Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run), filter, router, routeValuesFactory);
|
|
|
|
|
|
|
|
|
|
private UmbracoRouteValueTransformer GetTransformer(
|
|
|
|
|
IUmbracoContextAccessor ctx,
|
|
|
|
|
IRuntimeState state,
|
|
|
|
|
IRoutableDocumentFilter filter = null,
|
|
|
|
|
IPublishedRouter router = null,
|
|
|
|
|
IUmbracoRouteValuesFactory routeValuesFactory = null)
|
|
|
|
|
{
|
2021-09-21 10:49:45 -06:00
|
|
|
var publicAccessRequestHandler = new Mock<IPublicAccessRequestHandler>();
|
|
|
|
|
publicAccessRequestHandler.Setup(x => x.RewriteForPublishedContentAccessAsync(It.IsAny<HttpContext>(), It.IsAny<UmbracoRouteValues>()))
|
|
|
|
|
.Returns((HttpContext ctx, UmbracoRouteValues routeVals) => Task.FromResult(routeVals));
|
|
|
|
|
|
2021-01-13 11:08:48 +11:00
|
|
|
var transformer = new UmbracoRouteValueTransformer(
|
|
|
|
|
new NullLogger<UmbracoRouteValueTransformer>(),
|
|
|
|
|
ctx,
|
|
|
|
|
router ?? Mock.Of<IPublishedRouter>(),
|
|
|
|
|
GetGlobalSettings(),
|
|
|
|
|
TestHelper.GetHostingEnvironment(),
|
|
|
|
|
state,
|
|
|
|
|
routeValuesFactory ?? Mock.Of<IUmbracoRouteValuesFactory>(),
|
2021-02-03 15:47:27 +11:00
|
|
|
filter ?? Mock.Of<IRoutableDocumentFilter>(x => x.IsDocumentRequest(It.IsAny<string>()) == true),
|
|
|
|
|
Mock.Of<IDataProtectionProvider>(),
|
2021-03-01 14:20:15 +11:00
|
|
|
Mock.Of<IControllerActionSearcher>(),
|
2021-09-21 10:49:45 -06:00
|
|
|
Mock.Of<IEventAggregator>(),
|
|
|
|
|
publicAccessRequestHandler.Object);
|
2021-01-13 11:08:48 +11:00
|
|
|
|
|
|
|
|
return transformer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUmbracoContext GetUmbracoContext(bool hasContent)
|
|
|
|
|
{
|
|
|
|
|
IPublishedContentCache publishedContent = Mock.Of<IPublishedContentCache>(x => x.HasContent() == hasContent);
|
|
|
|
|
var uri = new Uri("http://example.com");
|
|
|
|
|
|
|
|
|
|
IUmbracoContext umbracoContext = Mock.Of<IUmbracoContext>(x =>
|
|
|
|
|
x.Content == publishedContent
|
|
|
|
|
&& x.OriginalRequestUrl == uri
|
|
|
|
|
&& x.CleanedUmbracoUrl == uri);
|
|
|
|
|
|
|
|
|
|
return umbracoContext;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private UmbracoRouteValues GetRouteValues(IPublishedRequest request)
|
|
|
|
|
=> new UmbracoRouteValues(
|
|
|
|
|
request,
|
2021-02-04 13:09:28 +11:00
|
|
|
new ControllerActionDescriptor
|
|
|
|
|
{
|
|
|
|
|
ControllerTypeInfo = typeof(TestController).GetTypeInfo(),
|
|
|
|
|
ControllerName = ControllerExtensions.GetControllerName<TestController>()
|
|
|
|
|
});
|
2021-01-13 11:08:48 +11:00
|
|
|
|
|
|
|
|
private IUmbracoRouteValuesFactory GetRouteValuesFactory(IPublishedRequest request)
|
Implements Public Access in netcore (#10137)
* Getting new netcore PublicAccessChecker in place
* Adds full test coverage for PublicAccessChecker
* remove PublicAccessComposer
* adjust namespaces, ensure RoleManager works, separate public access controller, reduce content controller
* Implements the required methods on IMemberManager, removes old migrated code
* Updates routing to be able to re-route, Fixes middleware ordering ensuring endpoints are last, refactors pipeline options, adds public access middleware, ensures public access follows all hops
* adds note
* adds note
* Cleans up ext methods, ensures that members identity is added on both front-end and back ends. updates how UmbracoApplicationBuilder works in that it explicitly starts endpoints at the time of calling.
* Changes name to IUmbracoEndpointBuilder
* adds note
* Fixing tests, fixing error describers so there's 2x one for back office, one for members, fixes TryConvertTo, fixes login redirect
* fixing build
* Fixes keepalive, fixes PublicAccessMiddleware to not throw, updates startup code to be more clear and removes magic that registers middleware.
* adds note
* removes unused filter, fixes build
* fixes WebPath and tests
* Looks up entities in one query
* remove usings
* Fix test, remove stylesheet
* Set status code before we write to response to avoid error
* Ensures that users and members are validated when logging in. Shares more code between users and members.
* Fixes RepositoryCacheKeys to ensure the keys are normalized
* oops didn't mean to commit this
* Fix casing issues with caching, stop boxing value types for all cache operations, stop re-creating string keys in DefaultRepositoryCachePolicy
* bah, far out this keeps getting recommitted. sorry
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
2021-04-20 15:11:45 +10:00
|
|
|
=> Mock.Of<IUmbracoRouteValuesFactory>(x => x.CreateAsync(It.IsAny<HttpContext>(), It.IsAny<IPublishedRequest>()) == Task.FromResult(GetRouteValues(request)));
|
2021-01-13 11:08:48 +11:00
|
|
|
|
|
|
|
|
private IPublishedRouter GetRouter(IPublishedRequest request)
|
|
|
|
|
=> Mock.Of<IPublishedRouter>(x => x.RouteRequestAsync(It.IsAny<IPublishedRequestBuilder>(), It.IsAny<RouteRequestOptions>()) == Task.FromResult(request));
|
|
|
|
|
|
|
|
|
|
[Test]
|
2021-09-17 12:47:41 -06:00
|
|
|
public async Task Null_When_Runtime_Level_Not_Run()
|
2021-01-13 11:08:48 +11:00
|
|
|
{
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformer(
|
2021-01-13 12:35:05 +01:00
|
|
|
Mock.Of<IUmbracoContextAccessor>(),
|
2021-01-13 11:08:48 +11:00
|
|
|
Mock.Of<IRuntimeState>());
|
|
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
2021-09-17 12:47:41 -06:00
|
|
|
Assert.IsNull(result);
|
2021-01-13 11:08:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2021-09-17 12:47:41 -06:00
|
|
|
public async Task Null_When_No_Umbraco_Context()
|
2021-01-13 11:08:48 +11:00
|
|
|
{
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
2021-01-13 12:35:05 +01:00
|
|
|
Mock.Of<IUmbracoContextAccessor>());
|
2021-01-13 11:08:48 +11:00
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
2021-09-17 12:47:41 -06:00
|
|
|
Assert.IsNull(result);
|
2021-01-13 11:08:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
2021-09-17 12:47:41 -06:00
|
|
|
public async Task Null_When_Not_Document_Request()
|
2021-01-13 11:08:48 +11:00
|
|
|
{
|
2021-08-11 13:33:34 +02:00
|
|
|
var umbracoContext = Mock.Of<IUmbracoContext>();
|
2021-01-13 11:08:48 +11:00
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
2021-08-11 13:33:34 +02:00
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
2021-01-13 11:08:48 +11:00
|
|
|
Mock.Of<IRoutableDocumentFilter>(x => x.IsDocumentRequest(It.IsAny<string>()) == false));
|
|
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
2021-09-17 12:47:41 -06:00
|
|
|
Assert.IsNull(result);
|
2021-01-13 11:08:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task NoContentController_Values_When_No_Content()
|
|
|
|
|
{
|
|
|
|
|
IUmbracoContext umbracoContext = GetUmbracoContext(false);
|
|
|
|
|
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
2021-08-11 13:25:17 +02:00
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)));
|
2021-01-13 11:08:48 +11:00
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
|
|
|
|
Assert.AreEqual(2, result.Count);
|
2021-02-05 13:14:24 +11:00
|
|
|
Assert.AreEqual(ControllerExtensions.GetControllerName<RenderNoContentController>(), result[ControllerToken]);
|
|
|
|
|
Assert.AreEqual(nameof(RenderNoContentController.Index), result[ActionToken]);
|
2021-01-13 11:08:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task Assigns_PublishedRequest_To_UmbracoContext()
|
|
|
|
|
{
|
|
|
|
|
IUmbracoContext umbracoContext = GetUmbracoContext(true);
|
|
|
|
|
IPublishedRequest request = Mock.Of<IPublishedRequest>();
|
|
|
|
|
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
2021-08-11 13:25:17 +02:00
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
2021-01-13 11:08:48 +11:00
|
|
|
router: GetRouter(request),
|
|
|
|
|
routeValuesFactory: GetRouteValuesFactory(request));
|
|
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
|
|
|
|
Assert.AreEqual(request, umbracoContext.PublishedRequest);
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-03 15:47:27 +11:00
|
|
|
[Test]
|
2021-09-21 10:49:45 -06:00
|
|
|
public async Task Null_When_No_Content_On_PublishedRequest()
|
2021-02-03 15:47:27 +11:00
|
|
|
{
|
|
|
|
|
IUmbracoContext umbracoContext = GetUmbracoContext(true);
|
2021-09-26 20:42:27 +10:00
|
|
|
IPublishedRequest request = Mock.Of<IPublishedRequest>(x => x.PublishedContent == null);
|
2021-02-03 15:47:27 +11:00
|
|
|
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
2021-08-11 13:25:17 +02:00
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
2021-02-03 15:47:27 +11:00
|
|
|
router: GetRouter(request),
|
|
|
|
|
routeValuesFactory: GetRouteValuesFactory(request));
|
|
|
|
|
|
|
|
|
|
var httpContext = new DefaultHttpContext();
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(httpContext, new RouteValueDictionary());
|
2021-09-26 20:42:27 +10:00
|
|
|
Assert.IsNull(result);
|
2021-02-03 15:47:27 +11:00
|
|
|
|
2021-09-21 10:49:45 -06:00
|
|
|
UmbracoRouteValues routeVals = httpContext.Features.Get<UmbracoRouteValues>();
|
2021-09-26 20:42:27 +10:00
|
|
|
Assert.AreEqual(routeVals.PublishedRequest.GetRouteResult(), UmbracoRouteResult.NotFound);
|
2021-09-21 10:49:45 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
|
public async Task Assigns_UmbracoRouteValues_To_HttpContext_Feature()
|
|
|
|
|
{
|
|
|
|
|
IUmbracoContext umbracoContext = GetUmbracoContext(true);
|
|
|
|
|
IPublishedRequest request = Mock.Of<IPublishedRequest>(x => x.PublishedContent == Mock.Of<IPublishedContent>());
|
|
|
|
|
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
|
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
|
|
|
|
router: GetRouter(request),
|
|
|
|
|
routeValuesFactory: GetRouteValuesFactory(request));
|
|
|
|
|
|
|
|
|
|
var httpContext = new DefaultHttpContext();
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(httpContext, new RouteValueDictionary());
|
|
|
|
|
|
2021-02-03 15:47:27 +11:00
|
|
|
UmbracoRouteValues routeVals = httpContext.Features.Get<UmbracoRouteValues>();
|
|
|
|
|
Assert.IsNotNull(routeVals);
|
|
|
|
|
Assert.AreEqual(routeVals.PublishedRequest, umbracoContext.PublishedRequest);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-13 11:08:48 +11:00
|
|
|
[Test]
|
2021-09-17 12:47:41 -06:00
|
|
|
public async Task Assigns_Values_To_RouteValueDictionary_When_Content()
|
2021-01-13 11:08:48 +11:00
|
|
|
{
|
|
|
|
|
IUmbracoContext umbracoContext = GetUmbracoContext(true);
|
2021-09-17 12:47:41 -06:00
|
|
|
IPublishedRequest request = Mock.Of<IPublishedRequest>(x => x.PublishedContent == Mock.Of<IPublishedContent>());
|
2021-01-13 11:08:48 +11:00
|
|
|
UmbracoRouteValues routeValues = GetRouteValues(request);
|
|
|
|
|
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
2021-08-11 13:25:17 +02:00
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
2021-01-13 11:08:48 +11:00
|
|
|
router: GetRouter(request),
|
|
|
|
|
routeValuesFactory: GetRouteValuesFactory(request));
|
|
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
|
|
|
|
|
2021-02-05 13:14:24 +11:00
|
|
|
Assert.AreEqual(routeValues.ControllerName, result[ControllerToken]);
|
|
|
|
|
Assert.AreEqual(routeValues.ActionName, result[ActionToken]);
|
2021-01-13 11:08:48 +11:00
|
|
|
}
|
|
|
|
|
|
2021-09-17 12:47:41 -06:00
|
|
|
[Test]
|
|
|
|
|
public async Task Returns_Null_RouteValueDictionary_When_No_Content()
|
|
|
|
|
{
|
|
|
|
|
IUmbracoContext umbracoContext = GetUmbracoContext(true);
|
|
|
|
|
IPublishedRequest request = Mock.Of<IPublishedRequest>(x => x.PublishedContent == null);
|
|
|
|
|
UmbracoRouteValues routeValues = GetRouteValues(request);
|
|
|
|
|
|
|
|
|
|
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
|
|
|
|
|
Mock.Of<IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
|
|
|
|
|
router: GetRouter(request),
|
|
|
|
|
routeValuesFactory: GetRouteValuesFactory(request));
|
|
|
|
|
|
|
|
|
|
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
|
|
|
|
|
|
|
|
|
|
Assert.IsNull(result);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-13 11:08:48 +11:00
|
|
|
private class TestController : RenderController
|
|
|
|
|
{
|
2021-02-17 12:00:57 +01:00
|
|
|
public TestController(ILogger<TestController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor)
|
|
|
|
|
: base(logger, compositeViewEngine, umbracoContextAccessor)
|
2021-01-13 11:08:48 +11:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|