v14: Remove mentions of UmbracoApiController (#15863)

* Remove mentions of UmbracoApiController

* Remove last mentions of UmbracoApi controller
This commit is contained in:
Nikolaj Geisle
2024-03-19 14:42:08 +01:00
committed by GitHub
parent 08783c6065
commit 30e2dea57a
17 changed files with 3 additions and 626 deletions

View File

@@ -19,7 +19,6 @@ namespace Umbraco.Cms.Api.Management.Routing;
/// </summary>
public sealed class BackOfficeAreaRoutes : IAreaRoutes
{
private readonly UmbracoApiControllerTypeCollection _apiControllers;
private readonly GlobalSettings _globalSettings;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IRuntimeState _runtimeState;
@@ -31,13 +30,11 @@ public sealed class BackOfficeAreaRoutes : IAreaRoutes
public BackOfficeAreaRoutes(
IOptions<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment,
IRuntimeState runtimeState,
UmbracoApiControllerTypeCollection apiControllers)
IRuntimeState runtimeState)
{
_globalSettings = globalSettings.Value;
_hostingEnvironment = hostingEnvironment;
_runtimeState = runtimeState;
_apiControllers = apiControllers;
_umbracoPathSegment = _globalSettings.GetUmbracoMvcArea(_hostingEnvironment);
}
@@ -53,7 +50,6 @@ public sealed class BackOfficeAreaRoutes : IAreaRoutes
case RuntimeLevel.Run:
MapMinimalBackOffice(endpoints);
AutoRouteBackOfficeApiControllers(endpoints);
break;
case RuntimeLevel.BootFailed:
case RuntimeLevel.Unknown:
@@ -87,33 +83,4 @@ public sealed class BackOfficeAreaRoutes : IAreaRoutes
Action = nameof(BackOfficeDefaultController.Index)
});
}
/// <summary>
/// Auto-routes all back office api controllers
/// </summary>
private void AutoRouteBackOfficeApiControllers(IEndpointRouteBuilder endpoints)
{
// TODO: We could investigate dynamically routing plugin controllers so we don't have to eagerly type scan for them,
// it would probably work well, see https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/
// will probably be what we use for front-end routing too. BTW the orig article about migrating from IRouter to endpoint
// routing for things like a CMS is here https://github.com/dotnet/aspnetcore/issues/4221
foreach (Type controller in _apiControllers)
{
PluginControllerMetadata meta = PluginController.GetMetadata(controller);
// exclude front-end api controllers
if (!meta.IsBackOffice)
{
continue;
}
endpoints.MapUmbracoApiRoute(
meta.ControllerType,
_umbracoPathSegment,
meta.AreaName,
meta.IsBackOffice,
string.Empty); // no default action (this is what we had before)
}
}
}

View File

@@ -1,11 +0,0 @@
using Umbraco.Cms.Core.Composing;
namespace Umbraco.Cms.Core;
public class UmbracoApiControllerTypeCollection : BuilderCollectionBase<Type>
{
public UmbracoApiControllerTypeCollection(Func<IEnumerable<Type>> items)
: base(items)
{
}
}

View File

@@ -1,11 +0,0 @@
using Umbraco.Cms.Web.Common.ApplicationModels;
namespace Umbraco.Cms.Web.Common.Attributes;
/// <summary>
/// When present on a controller then <see cref="UmbracoApiBehaviorApplicationModelProvider" /> conventions will apply
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public sealed class UmbracoApiControllerAttribute : Attribute
{
}

View File

@@ -1,16 +0,0 @@
using Umbraco.Cms.Core.Composing;
namespace Umbraco.Cms.Web.Common.Controllers;
/// <summary>
/// Provides a base class for auto-routed Umbraco API controllers.
/// </summary>
public abstract class UmbracoApiController : UmbracoApiControllerBase, IDiscoverable
{
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoApiController" /> class.
/// </summary>
protected UmbracoApiController()
{
}
}

View File

@@ -1,26 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Features;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.Authorization;
namespace Umbraco.Cms.Web.Common.Controllers;
/// <summary>
/// Provides a base class for Umbraco API controllers.
/// </summary>
/// <remarks>
/// <para>These controllers are NOT auto-routed.</para>
/// <para>The base class is <see cref="ControllerBase" /> which are netcore API controllers without any view support</para>
/// </remarks>
[Authorize(Policy = AuthorizationPolicies.UmbracoFeatureEnabled)] // TODO: This could be part of our conventions
[UmbracoApiController]
public abstract class UmbracoApiControllerBase : ControllerBase, IUmbracoFeature
{
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoApiControllerBase" /> class.
/// </summary>
protected UmbracoApiControllerBase()
{
}
}

View File

@@ -1,11 +0,0 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Composing;
namespace Umbraco.Cms.Web.Common.Controllers;
public class UmbracoApiControllerTypeCollectionBuilder : TypeCollectionBuilderBase<
UmbracoApiControllerTypeCollectionBuilder, UmbracoApiControllerTypeCollection, UmbracoApiController>
{
// TODO: Should this only exist in the back office project? These really are only ever used for the back office AFAIK
protected override UmbracoApiControllerTypeCollectionBuilder This => this;
}

View File

@@ -290,10 +290,6 @@ public static partial class UmbracoBuilderExtensions
builder.Services.AddUnique<IUmbracoContextFactory, UmbracoContextFactory>();
builder.Services.AddUnique<IBackOfficeSecurityAccessor, BackOfficeSecurityAccessor>();
var umbracoApiControllerTypes = builder.TypeLoader.GetUmbracoApiControllers().ToList();
builder.WithCollectionBuilder<UmbracoApiControllerTypeCollectionBuilder>()
.Add(umbracoApiControllerTypes);
builder.Services.AddSingleton<UmbracoRequestLoggingMiddleware>();
builder.Services.AddSingleton<PreviewAuthenticationMiddleware>();
builder.Services.AddSingleton<UmbracoRequestMiddleware>();

View File

@@ -12,64 +12,6 @@ namespace Umbraco.Extensions;
public static class LinkGeneratorExtensions
{
/// <summary>
/// Gets the Umbraco backoffice URL (if Umbraco is installed).
/// </summary>
/// <param name="linkGenerator">The link generator.</param>
/// <returns>
/// The Umbraco backoffice URL.
/// </returns>
public static string? GetUmbracoBackOfficeUrl(this LinkGenerator linkGenerator)
=> linkGenerator.GetPathByAction("Default", "BackOffice", new { area = Constants.Web.Mvc.BackOfficeArea });
/// <summary>
/// Gets the Umbraco backoffice URL (if Umbraco is installed) or application virtual path (in most cases just <c>"/"</c>).
/// </summary>
/// <param name="linkGenerator">The link generator.</param>
/// <param name="hostingEnvironment">The hosting environment.</param>
/// <returns>
/// The Umbraco backoffice URL.
/// </returns>
public static string GetUmbracoBackOfficeUrl(this LinkGenerator linkGenerator, IHostingEnvironment hostingEnvironment)
=> GetUmbracoBackOfficeUrl(linkGenerator) ?? hostingEnvironment.ApplicationVirtualPath;
/// <summary>
/// Return the back office url if the back office is installed
/// </summary>
/// <remarks>
/// This method contained a bug that would result in always returning "/".
/// </remarks>
[Obsolete("Use the GetUmbracoBackOfficeUrl extension method instead. This method will be removed in Umbraco 13.")]
public static string? GetBackOfficeUrl(this LinkGenerator linkGenerator, IHostingEnvironment hostingEnvironment)
=> "/";
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <typeparam name="T">The <see cref="UmbracoApiControllerBase" /></typeparam>
public static string? GetUmbracoApiService<T>(this LinkGenerator linkGenerator, string actionName, object? id = null)
where T : UmbracoApiControllerBase => linkGenerator.GetUmbracoControllerUrl(
actionName,
typeof(T),
new Dictionary<string, object?> { ["id"] = id });
public static string? GetUmbracoApiService<T>(this LinkGenerator linkGenerator, string actionName, IDictionary<string, object?>? values)
where T : UmbracoApiControllerBase => linkGenerator.GetUmbracoControllerUrl(actionName, typeof(T), values);
public static string? GetUmbracoApiServiceBaseUrl<T>(
this LinkGenerator linkGenerator,
Expression<Func<T, object?>> methodSelector)
where T : UmbracoApiControllerBase
{
MethodInfo? method = ExpressionHelper.GetMethodInfo(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) +
" or the result ");
}
return linkGenerator.GetUmbracoApiService<T>(method.Name)?.TrimEnd(method.Name);
}
/// <summary>
/// Return the Url for an Umbraco controller
@@ -159,25 +101,4 @@ public static class LinkGeneratorExtensions
return linkGenerator.GetUmbracoControllerUrl(actionName, ControllerExtensions.GetControllerName(controllerType), area, values);
}
public static string? GetUmbracoApiService<T>(
this LinkGenerator linkGenerator,
Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
MethodInfo? method = ExpressionHelper.GetMethodInfo(methodSelector);
IDictionary<string, object?>? methodParams = ExpressionHelper.GetMethodParams(methodSelector);
if (method == null)
{
throw new MissingMethodException(
$"Could not find the method {methodSelector} on type {typeof(T)} or the result ");
}
if (methodParams?.Any() == false)
{
return linkGenerator.GetUmbracoApiService<T>(method.Name);
}
return linkGenerator.GetUmbracoApiService<T>(method.Name, methodParams);
}
}

View File

@@ -1,13 +0,0 @@
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Web.Common.Controllers;
namespace Umbraco.Extensions;
public static class TypeLoaderExtensions
{
/// <summary>
/// Gets all types implementing <see cref="UmbracoApiController" />.
/// </summary>
public static IEnumerable<Type> GetUmbracoApiControllers(this TypeLoader typeLoader)
=> typeLoader.GetTypes<UmbracoApiController>();
}

View File

@@ -21,236 +21,6 @@ namespace Umbraco.Extensions;
public static class UrlHelperExtensions
{
/// <summary>
/// Gets the Umbraco backoffice URL (if Umbraco is installed).
/// </summary>
/// <param name="urlHelper">The URL helper.</param>
/// <returns>
/// The Umbraco backoffice URL.
/// </returns>
public static string? GetUmbracoBackOfficeUrl(this IUrlHelper urlHelper)
=> urlHelper.Action("Default", "BackOffice", new { area = Constants.Web.Mvc.BackOfficeArea });
/// <summary>
/// Return the back office url if the back office is installed
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
/// <remarks>
/// This method contained a bug that would result in always returning "/".
/// </remarks>
[Obsolete("Use the GetUmbracoBackOfficeUrl extension method instead. This method will be removed in Umbraco 13.")]
public static string? GetBackOfficeUrl(this IUrlHelper url)
=> "/";
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="umbracoApiControllerTypeCollection"></param>
/// <param name="actionName"></param>
/// <param name="id"></param>
/// <returns></returns>
public static string? GetUmbracoApiService<T>(
this IUrlHelper url,
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
string actionName,
object? id = null)
where T : UmbracoApiController =>
url.GetUmbracoApiService(umbracoApiControllerTypeCollection, actionName, typeof(T), id);
public static string? GetUmbracoApiService<T>(
this IUrlHelper url,
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
MethodInfo? method = ExpressionHelper.GetMethodInfo(methodSelector);
IDictionary<string, object?>? methodParams = ExpressionHelper.GetMethodParams(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) +
" or the result ");
}
if (methodParams?.Any() == false)
{
return url.GetUmbracoApiService<T>(umbracoApiControllerTypeCollection, method.Name);
}
return url.GetUmbracoApiService<T>(umbracoApiControllerTypeCollection, method.Name, methodParams?.Values.First());
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="umbracoApiControllerTypeCollection"></param>
/// <param name="actionName"></param>
/// <param name="apiControllerType"></param>
/// <param name="id"></param>
/// <returns></returns>
public static string? GetUmbracoApiService(
this IUrlHelper url,
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
string actionName,
Type apiControllerType,
object? id = null)
{
if (actionName == null)
{
throw new ArgumentNullException(nameof(actionName));
}
if (string.IsNullOrWhiteSpace(actionName))
{
throw new ArgumentException(
"Value can't be empty or consist only of white-space characters.",
nameof(actionName));
}
if (apiControllerType == null)
{
throw new ArgumentNullException(nameof(apiControllerType));
}
var area = string.Empty;
Type? apiController = umbracoApiControllerTypeCollection.SingleOrDefault(x => x == apiControllerType);
if (apiController == null)
{
throw new InvalidOperationException("Could not find the umbraco api controller of type " +
apiControllerType.FullName);
}
PluginControllerMetadata metaData = PluginController.GetMetadata(apiController);
if (metaData.AreaName.IsNullOrWhiteSpace() == false)
{
// set the area to the plugin area
area = metaData.AreaName;
}
return url.GetUmbracoApiService(actionName, ControllerExtensions.GetControllerName(apiControllerType), area!, id);
}
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="id"></param>
/// <returns></returns>
public static string? GetUmbracoApiService(this IUrlHelper url, string actionName, string controllerName, object? id = null) => url.GetUmbracoApiService(actionName, controllerName, string.Empty, id);
/// <summary>
/// Return the Url for a Web Api service
/// </summary>
/// <param name="url"></param>
/// <param name="actionName"></param>
/// <param name="controllerName"></param>
/// <param name="area"></param>
/// <param name="id"></param>
/// <returns></returns>
public static string? GetUmbracoApiService(
this IUrlHelper url,
string actionName,
string controllerName,
string area,
object? id = null)
{
if (actionName == null)
{
throw new ArgumentNullException(nameof(actionName));
}
if (string.IsNullOrWhiteSpace(actionName))
{
throw new ArgumentException(
"Value can't be empty or consist only of white-space characters.",
nameof(actionName));
}
if (controllerName == null)
{
throw new ArgumentNullException(nameof(controllerName));
}
if (string.IsNullOrWhiteSpace(controllerName))
{
throw new ArgumentException(
"Value can't be empty or consist only of white-space characters.",
nameof(controllerName));
}
if (area.IsNullOrWhiteSpace())
{
if (id == null)
{
return url.Action(actionName, controllerName);
}
return url.Action(actionName, controllerName, new { id });
}
if (id == null)
{
return url.Action(actionName, controllerName, new { area });
}
return url.Action(actionName, controllerName, new { area, id });
}
/// <summary>
/// Return the Base Url (not including the action) for a Web Api service
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="umbracoApiControllerTypeCollection"></param>
/// <param name="actionName"></param>
/// <returns></returns>
public static string? GetUmbracoApiServiceBaseUrl<T>(
this IUrlHelper url,
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
string actionName)
where T : UmbracoApiController =>
url.GetUmbracoApiService<T>(umbracoApiControllerTypeCollection, actionName)?.TrimEnd(actionName);
public static string? GetUmbracoApiServiceBaseUrl<T>(
this IUrlHelper url,
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
MethodInfo? method = ExpressionHelper.GetMethodInfo(methodSelector);
if (method == null)
{
throw new MissingMethodException("Could not find the method " + methodSelector + " on type " + typeof(T) +
" or the result ");
}
return url.GetUmbracoApiService<T>(umbracoApiControllerTypeCollection, method.Name)?.TrimEnd(method.Name);
}
/// <summary>
/// Return the Url for an action with a cache-busting hash appended
/// </summary>
/// <returns></returns>
public static string GetUrlWithCacheBust(
this IUrlHelper url,
string actionName,
string controllerName,
RouteValueDictionary routeVals,
IHostingEnvironment hostingEnvironment,
IUmbracoVersion umbracoVersion)
{
var applicationJs = url.Action(actionName, controllerName, routeVals);
applicationJs = applicationJs + "?umb__rnd=" +
GetCacheBustHash(hostingEnvironment, umbracoVersion);
return applicationJs;
}
/// <summary>
/// </summary>
/// <returns></returns>

View File

@@ -60,17 +60,7 @@ public sealed class ConfigureMemberCookieOptions : IConfigureNamedOptions<Cookie
},
OnRedirectToAccessDenied = ctx =>
{
// When the controller is an UmbracoAPIController, we want to return a StatusCode instead of a redirect.
// All other cases should use the default Redirect of the CookieAuthenticationEvent.
var controllerDescriptor = ctx.HttpContext.GetEndpoint()?.Metadata
.OfType<ControllerActionDescriptor>()
.FirstOrDefault();
if (!controllerDescriptor?.ControllerTypeInfo.IsSubclassOf(typeof(UmbracoApiController)) ?? false)
{
new CookieAuthenticationEvents().OnRedirectToAccessDenied(ctx);
}
new CookieAuthenticationEvents().OnRedirectToAccessDenied(ctx);
return Task.CompletedTask;
},
};

View File

@@ -15,10 +15,4 @@ public static class TypeLoaderExtensions
/// </summary>
internal static IEnumerable<Type> GetSurfaceControllers(this TypeLoader typeLoader)
=> typeLoader.GetTypes<SurfaceController>();
/// <summary>
/// Gets all types implementing <see cref="UmbracoApiController" />.
/// </summary>
internal static IEnumerable<Type> GetUmbracoApiControllers(this TypeLoader typeLoader)
=> typeLoader.GetTypes<UmbracoApiController>();
}

View File

@@ -17,7 +17,6 @@ namespace Umbraco.Cms.Web.Website.Routing;
/// </summary>
public sealed class FrontEndRoutes : IAreaRoutes
{
private readonly UmbracoApiControllerTypeCollection _apiControllers;
private readonly IRuntimeState _runtimeState;
private readonly SurfaceControllerTypeCollection _surfaceControllerTypeCollection;
private readonly string _umbracoPathSegment;
@@ -29,12 +28,10 @@ public sealed class FrontEndRoutes : IAreaRoutes
IOptions<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment,
IRuntimeState runtimeState,
SurfaceControllerTypeCollection surfaceControllerTypeCollection,
UmbracoApiControllerTypeCollection apiControllers)
SurfaceControllerTypeCollection surfaceControllerTypeCollection)
{
_runtimeState = runtimeState;
_surfaceControllerTypeCollection = surfaceControllerTypeCollection;
_apiControllers = apiControllers;
_umbracoPathSegment = globalSettings.Value.GetUmbracoMvcArea(hostingEnvironment);
}
@@ -48,7 +45,6 @@ public sealed class FrontEndRoutes : IAreaRoutes
case RuntimeLevel.Run:
AutoRouteSurfaceControllers(endpoints);
AutoRouteFrontEndApiControllers(endpoints);
break;
case RuntimeLevel.BootFailed:
case RuntimeLevel.Unknown:
@@ -75,28 +71,4 @@ public sealed class FrontEndRoutes : IAreaRoutes
meta.AreaName);
}
}
/// <summary>
/// Auto-routes all front-end api controllers
/// </summary>
private void AutoRouteFrontEndApiControllers(IEndpointRouteBuilder endpoints)
{
foreach (Type controller in _apiControllers)
{
PluginControllerMetadata meta = PluginController.GetMetadata(controller);
// exclude back-end api controllers
if (meta.IsBackOffice)
{
continue;
}
endpoints.MapUmbracoApiRoute(
meta.ControllerType,
_umbracoPathSegment,
meta.AreaName,
meta.IsBackOffice,
string.Empty); // no default action (this is what we had before)
}
}
}

View File

@@ -105,18 +105,6 @@ namespace Umbraco.Cms.Tests.Integration.TestServerTest
});
}
/// <summary>
/// Prepare a url before using <see cref="Client"/>.
/// This returns the url but also sets the HttpContext.request into to use this url.
/// </summary>
/// <returns>The string URL of the controller action.</returns>
protected string PrepareApiControllerUrl<T>(Expression<Func<T, object>> methodSelector)
where T : UmbracoApiController
{
var url = LinkGenerator.GetUmbracoApiService(methodSelector);
return PrepareUrl(url);
}
protected string GetManagementApiUrl<T>(Expression<Func<T, object>> methodSelector)
where T : ManagementApiControllerBase
{

View File

@@ -67,36 +67,6 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.Website.Security
Assert.AreEqual(HttpStatusCode.Redirect, response.StatusCode);
Assert.AreEqual(cookieAuthenticationOptions.Value.AccessDeniedPath.ToString(), response.Headers.Location?.AbsolutePath);
}
[Test]
[LongRunning]
public async Task Secure_ApiController_Should_Return_Unauthorized_WhenNotLoggedIn()
{
_memberManagerMock.Setup(x => x.IsLoggedIn()).Returns(false);
var url = PrepareApiControllerUrl<TestApiController>(x => x.Secure());
var response = await Client.GetAsync(url);
Assert.AreEqual(HttpStatusCode.Unauthorized, response.StatusCode);
}
[Test]
[LongRunning]
public async Task Secure_ApiController_Should_Return_Forbidden_WhenNotAuthorized()
{
_memberManagerMock.Setup(x => x.IsLoggedIn()).Returns(true);
_memberManagerMock.Setup(x => x.IsMemberAuthorizedAsync(
It.IsAny<IEnumerable<string>>(),
It.IsAny<IEnumerable<string>>(),
It.IsAny<IEnumerable<int>>()))
.ReturnsAsync(false);
var url = PrepareApiControllerUrl<TestApiController>(x => x.Secure());
var response = await Client.GetAsync(url);
Assert.AreEqual(HttpStatusCode.Forbidden, response.StatusCode);
}
}
public class TestSurfaceController : SurfaceController
@@ -121,10 +91,4 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Web.Website.Security
[UmbracoMemberAuthorize]
public IActionResult Secure() => NoContent();
}
public class TestApiController : UmbracoApiController
{
[UmbracoMemberAuthorize]
public IActionResult Secure() => NoContent();
}
}

View File

@@ -46,14 +46,6 @@ internal class UmbracoCustomizations : ICustomization
fixture.Customize<HostingSettings>(x =>
x.With(settings => settings.ApplicationVirtualPath, string.Empty));
fixture.Customize<BackOfficeAreaRoutes>(u => u.FromFactory(
() => new BackOfficeAreaRoutes(
Options.Create(new GlobalSettings()),
Mock.Of<IHostingEnvironment>(x =>
x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run),
new UmbracoApiControllerTypeCollection(Enumerable.Empty<Type>))));
fixture.Customize<PreviewRoutes>(u => u.FromFactory(
() => new PreviewRoutes(
Options.Create(new GlobalSettings()),

View File

@@ -1,89 +0,0 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Api.Management.Controllers.Security;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.Controllers;
using Umbraco.Extensions;
using static Umbraco.Cms.Core.Constants.Web.Routing;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Common.Routing;
[TestFixture]
public class BackOfficeAreaRoutesTests
{
[TestCase(RuntimeLevel.BootFailed)]
[TestCase(RuntimeLevel.Unknown)]
[TestCase(RuntimeLevel.Boot)]
public void RuntimeState_No_Routes(RuntimeLevel level)
{
var routes = GetBackOfficeAreaRoutes(level);
var endpoints = new TestRouteBuilder();
routes.CreateRoutes(endpoints);
Assert.AreEqual(0, endpoints.DataSources.Count);
}
[Test]
[TestCase(RuntimeLevel.Run)]
[TestCase(RuntimeLevel.Upgrade)]
[TestCase(RuntimeLevel.Install)]
public void RuntimeState_All_Routes(RuntimeLevel level)
{
var routes = GetBackOfficeAreaRoutes(level);
var endpoints = new TestRouteBuilder();
routes.CreateRoutes(endpoints);
Assert.AreEqual(1, endpoints.DataSources.Count);
var route = endpoints.DataSources.First();
Assert.AreEqual(3, route.Endpoints.Count);
AssertMinimalBackOfficeRoutes(route);
var endpoint4 = (RouteEndpoint)route.Endpoints[2];
var apiControllerName = ControllerExtensions.GetControllerName<Testing1Controller>();
Assert.AreEqual(
$"umbraco/backoffice/api/{apiControllerName.ToLowerInvariant()}/{{action}}/{{id?}}",
endpoint4.RoutePattern.RawText);
Assert.IsFalse(endpoint4.RoutePattern.Defaults.ContainsKey(AreaToken));
Assert.IsFalse(endpoint4.RoutePattern.Defaults.ContainsKey(ActionToken));
Assert.AreEqual(apiControllerName, endpoint4.RoutePattern.Defaults[ControllerToken]);
}
private void AssertMinimalBackOfficeRoutes(EndpointDataSource route)
{
var endpoint1 = (RouteEndpoint)route.Endpoints[0];
Assert.AreEqual("umbraco/{action}/{id?}", endpoint1.RoutePattern.RawText);
Assert.AreEqual("Index", endpoint1.RoutePattern.Defaults[ActionToken]);
Assert.AreEqual(ControllerExtensions.GetControllerName<BackOfficeDefaultController>(), endpoint1.RoutePattern.Defaults[ControllerToken]);
}
private BackOfficeAreaRoutes GetBackOfficeAreaRoutes(RuntimeLevel level)
{
var globalSettings = new GlobalSettings();
var routes = new BackOfficeAreaRoutes(
Options.Create(globalSettings),
Mock.Of<IHostingEnvironment>(x =>
x.ToAbsolute(It.IsAny<string>()) == "/umbraco" && x.ApplicationVirtualPath == string.Empty),
Mock.Of<IRuntimeState>(x => x.Level == level),
new UmbracoApiControllerTypeCollection(() => new[] { typeof(Testing1Controller) }));
return routes;
}
[IsBackOffice]
private class Testing1Controller : UmbracoApiController
{
}
}