Skip to content

Commit d6f4937

Browse files
committed
Fix unit test
1 parent 721eee2 commit d6f4937

File tree

11 files changed

+183
-20
lines changed

11 files changed

+183
-20
lines changed

src/Umbraco.Core/DeliveryApi/ApiContentRouteBuilder.cs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
using Microsoft.Extensions.Options;
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Microsoft.Extensions.Options;
23
using Umbraco.Cms.Core.Configuration.Models;
4+
using Umbraco.Cms.Core.DependencyInjection;
35
using Umbraco.Cms.Core.Models.DeliveryApi;
46
using Umbraco.Cms.Core.Models.PublishedContent;
57
using Umbraco.Cms.Core.PublishedCache;
@@ -16,6 +18,7 @@ public sealed class ApiContentRouteBuilder : IApiContentRouteBuilder
1618
private readonly IRequestPreviewService _requestPreviewService;
1719
private readonly IPublishedContentCache _contentCache;
1820
private readonly IDocumentNavigationQueryService _navigationQueryService;
21+
private readonly IPublishStatusQueryService _publishStatusQueryService;
1922
private RequestHandlerSettings _requestSettings;
2023

2124
public ApiContentRouteBuilder(
@@ -25,18 +28,41 @@ public ApiContentRouteBuilder(
2528
IRequestPreviewService requestPreviewService,
2629
IOptionsMonitor<RequestHandlerSettings> requestSettings,
2730
IPublishedContentCache contentCache,
28-
IDocumentNavigationQueryService navigationQueryService)
31+
IDocumentNavigationQueryService navigationQueryService,
32+
IPublishStatusQueryService publishStatusQueryService)
2933
{
3034
_apiContentPathProvider = apiContentPathProvider;
3135
_variationContextAccessor = variationContextAccessor;
3236
_requestPreviewService = requestPreviewService;
3337
_contentCache = contentCache;
3438
_navigationQueryService = navigationQueryService;
39+
_publishStatusQueryService = publishStatusQueryService;
3540
_globalSettings = globalSettings.Value;
3641
_requestSettings = requestSettings.CurrentValue;
3742
requestSettings.OnChange(settings => _requestSettings = settings);
3843
}
3944

45+
[Obsolete("Use constructor that takes an IPublishStatusQueryService instead, scheduled for removal in v17")]
46+
public ApiContentRouteBuilder(
47+
IApiContentPathProvider apiContentPathProvider,
48+
IOptions<GlobalSettings> globalSettings,
49+
IVariationContextAccessor variationContextAccessor,
50+
IRequestPreviewService requestPreviewService,
51+
IOptionsMonitor<RequestHandlerSettings> requestSettings,
52+
IPublishedContentCache contentCache,
53+
IDocumentNavigationQueryService navigationQueryService)
54+
: this(
55+
apiContentPathProvider,
56+
globalSettings,
57+
variationContextAccessor,
58+
requestPreviewService,
59+
requestSettings,
60+
contentCache,
61+
navigationQueryService,
62+
StaticServiceProvider.Instance.GetRequiredService<IPublishStatusQueryService>())
63+
{
64+
}
65+
4066
public IApiContentRoute? Build(IPublishedContent content, string? culture = null)
4167
{
4268
if (content.ItemType != PublishedItemType.Content)
@@ -105,7 +131,7 @@ private IPublishedContent GetRoot(IPublishedContent content, bool isPreview)
105131
{
106132
if (isPreview is false)
107133
{
108-
return content.Root(_contentCache, _navigationQueryService);
134+
return content.Root(_variationContextAccessor, _contentCache, _navigationQueryService, _publishStatusQueryService);
109135
}
110136

111137
_navigationQueryService.TryGetRootKeys(out IEnumerable<Guid> rootKeys);
@@ -114,6 +140,6 @@ private IPublishedContent GetRoot(IPublishedContent content, bool isPreview)
114140
// in very edge case scenarios during preview, content.Root() does not map to the root.
115141
// we'll code our way around it for the time being.
116142
return rootContent.FirstOrDefault(root => root.IsAncestorOrSelf(content))
117-
?? content.Root(_contentCache, _navigationQueryService);
143+
?? content.Root(_variationContextAccessor, _contentCache, _navigationQueryService, _publishStatusQueryService);
118144
}
119145
}

src/Umbraco.Core/Extensions/PublishedContentExtensions.cs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3155,6 +3155,29 @@ public static IEnumerable<T> SiblingsAndSelf<T>(
31553155

31563156
#region Axes: custom
31573157

3158+
/// <summary>
3159+
/// Gets the root content (ancestor or self at level 1) for the specified <paramref name="content" />.
3160+
/// </summary>
3161+
/// <param name="content">The content.</param>
3162+
/// <param name="variationContextAccessor"></param>
3163+
/// <param name="publishedCache">The content cache.</param>
3164+
/// <param name="navigationQueryService">The query service for the in-memory navigation structure.</param>
3165+
/// <param name="publishStatusQueryService"></param>
3166+
/// <returns>
3167+
/// The root content (ancestor or self at level 1) for the specified <paramref name="content" />.
3168+
/// </returns>
3169+
/// <remarks>
3170+
/// This is the same as calling
3171+
/// <see cref="AncestorOrSelf(IPublishedContent, int)" /> with <c>maxLevel</c>
3172+
/// set to 1.
3173+
/// </remarks>
3174+
public static IPublishedContent Root(
3175+
this IPublishedContent content,
3176+
IVariationContextAccessor variationContextAccessor,
3177+
IPublishedCache publishedCache,
3178+
INavigationQueryService navigationQueryService,
3179+
IPublishStatusQueryService publishStatusQueryService) => content.AncestorOrSelf(variationContextAccessor, publishedCache, navigationQueryService, publishStatusQueryService, 1);
3180+
31583181
/// <summary>
31593182
/// Gets the root content (ancestor or self at level 1) for the specified <paramref name="content" />.
31603183
/// </summary>
@@ -3169,19 +3192,27 @@ public static IEnumerable<T> SiblingsAndSelf<T>(
31693192
/// <see cref="AncestorOrSelf(IPublishedContent, int)" /> with <c>maxLevel</c>
31703193
/// set to 1.
31713194
/// </remarks>
3195+
[Obsolete("Use the overload with IVariationContextAccessor & IPublishStatusQueryService, scheduled for removal in v17")]
31723196
public static IPublishedContent Root(
31733197
this IPublishedContent content,
31743198
IPublishedCache publishedCache,
3175-
INavigationQueryService navigationQueryService) => content.AncestorOrSelf(publishedCache, navigationQueryService, 1);
3199+
INavigationQueryService navigationQueryService) => Root(
3200+
content,
3201+
StaticServiceProvider.Instance.GetRequiredService<IVariationContextAccessor>(),
3202+
publishedCache,
3203+
navigationQueryService,
3204+
StaticServiceProvider.Instance.GetRequiredService<IPublishStatusQueryService>());
31763205

31773206
/// <summary>
31783207
/// Gets the root content (ancestor or self at level 1) for the specified <paramref name="content" /> if it's of the
31793208
/// specified content type <typeparamref name="T" />.
31803209
/// </summary>
31813210
/// <typeparam name="T">The content type.</typeparam>
31823211
/// <param name="content">The content.</param>
3212+
/// <param name="variationContextAccessor"></param>
31833213
/// <param name="publishedCache">The content cache.</param>
31843214
/// <param name="navigationQueryService">The query service for the in-memory navigation structure.</param>
3215+
/// <param name="publishStatusQueryService"></param>
31853216
/// <returns>
31863217
/// The root content (ancestor or self at level 1) for the specified <paramref name="content" /> of content type
31873218
/// <typeparamref name="T" />.
@@ -3191,12 +3222,44 @@ public static IPublishedContent Root(
31913222
/// <see cref="AncestorOrSelf{T}(IPublishedContent, int)" /> with
31923223
/// <c>maxLevel</c> set to 1.
31933224
/// </remarks>
3225+
public static T? Root<T>(
3226+
this IPublishedContent content,
3227+
IVariationContextAccessor variationContextAccessor,
3228+
IPublishedCache publishedCache,
3229+
INavigationQueryService navigationQueryService,
3230+
IPublishStatusQueryService publishStatusQueryService)
3231+
where T : class, IPublishedContent =>
3232+
content.AncestorOrSelf<T>(variationContextAccessor, publishedCache, navigationQueryService, publishStatusQueryService, 1);
3233+
3234+
/// <summary>
3235+
/// Gets the root content (ancestor or self at level 1) for the specified <paramref name="content" /> if it's of the
3236+
/// specified content type <typeparamref name="T" />.
3237+
/// </summary>
3238+
/// <typeparam name="T">The content type.</typeparam>
3239+
/// <param name="content">The content.</param>
3240+
/// <param name="publishedCache">The content cache.</param>
3241+
/// <param name="navigationQueryService">The query service for the in-memory navigation structure.</param>
3242+
/// <returns>
3243+
/// The root content (ancestor or self at level 1) for the specified <paramref name="content" /> of content type
3244+
/// <typeparamref name="T" />.
3245+
/// </returns>
3246+
/// <remarks>
3247+
/// This is the same as calling
3248+
/// <see cref="AncestorOrSelf{T}(IPublishedContent, int)" /> with
3249+
/// <c>maxLevel</c> set to 1.
3250+
/// </remarks>
3251+
[Obsolete("Use the overload with IVariationContextAccessor & PublishStatusQueryService, scheduled for removal in v17")]
31943252
public static T? Root<T>(
31953253
this IPublishedContent content,
31963254
IPublishedCache publishedCache,
31973255
INavigationQueryService navigationQueryService)
31983256
where T : class, IPublishedContent =>
3199-
content.AncestorOrSelf<T>(publishedCache, navigationQueryService, 1);
3257+
Root<T>(
3258+
content,
3259+
StaticServiceProvider.Instance.GetRequiredService<IVariationContextAccessor>(),
3260+
publishedCache,
3261+
navigationQueryService,
3262+
StaticServiceProvider.Instance.GetRequiredService<IPublishStatusQueryService>());
32003263

32013264
#endregion
32023265

src/Umbraco.Core/Routing/ContentFinderByUrlAlias.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using Microsoft.Extensions.DependencyInjection;
12
using Microsoft.Extensions.Logging;
3+
using Umbraco.Cms.Core.DependencyInjection;
24
using Umbraco.Cms.Core.Models.PublishedContent;
35
using Umbraco.Cms.Core.PublishedCache;
46
using Umbraco.Cms.Core.Services.Navigation;
@@ -24,6 +26,7 @@ public class ContentFinderByUrlAlias : IContentFinder
2426
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
2527
private readonly IPublishedContentCache _contentCache;
2628
private readonly IDocumentNavigationQueryService _documentNavigationQueryService;
29+
private readonly IPublishStatusQueryService _publishStatusQueryService;
2730
private readonly IVariationContextAccessor _variationContextAccessor;
2831

2932
/// <summary>
@@ -35,16 +38,37 @@ public ContentFinderByUrlAlias(
3538
IVariationContextAccessor variationContextAccessor,
3639
IUmbracoContextAccessor umbracoContextAccessor,
3740
IPublishedContentCache contentCache,
38-
IDocumentNavigationQueryService documentNavigationQueryService)
41+
IDocumentNavigationQueryService documentNavigationQueryService,
42+
IPublishStatusQueryService publishStatusQueryService)
3943
{
4044
_publishedValueFallback = publishedValueFallback;
4145
_variationContextAccessor = variationContextAccessor;
4246
_umbracoContextAccessor = umbracoContextAccessor;
4347
_contentCache = contentCache;
4448
_documentNavigationQueryService = documentNavigationQueryService;
49+
_publishStatusQueryService = publishStatusQueryService;
4550
_logger = logger;
4651
}
4752

53+
[Obsolete("Please use constructor that takes an IPublishStatusQueryService instead. Scheduled removal in v17")]
54+
public ContentFinderByUrlAlias(
55+
ILogger<ContentFinderByUrlAlias> logger,
56+
IPublishedValueFallback publishedValueFallback,
57+
IVariationContextAccessor variationContextAccessor,
58+
IUmbracoContextAccessor umbracoContextAccessor,
59+
IPublishedContentCache contentCache,
60+
IDocumentNavigationQueryService documentNavigationQueryService)
61+
: this(
62+
logger,
63+
publishedValueFallback,
64+
variationContextAccessor,
65+
umbracoContextAccessor,
66+
contentCache,
67+
documentNavigationQueryService,
68+
StaticServiceProvider.Instance.GetRequiredService<IPublishStatusQueryService>())
69+
{
70+
}
71+
4872
/// <summary>
4973
/// Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
5074
/// </summary>
@@ -145,14 +169,14 @@ bool IsMatch(IPublishedContent c, string a1, string a2)
145169
if (rootNodeId > 0)
146170
{
147171
IPublishedContent? rootNode = cache?.GetById(rootNodeId);
148-
return rootNode?.Descendants(_variationContextAccessor, _contentCache, _documentNavigationQueryService).FirstOrDefault(x => IsMatch(x, test1, test2));
172+
return rootNode?.Descendants(_variationContextAccessor, _contentCache, _documentNavigationQueryService, _publishStatusQueryService).FirstOrDefault(x => IsMatch(x, test1, test2));
149173
}
150174

151175
if (cache is not null)
152176
{
153177
foreach (IPublishedContent rootContent in cache.GetAtRoot())
154178
{
155-
IPublishedContent? c = rootContent.DescendantsOrSelf(_variationContextAccessor, _contentCache, _documentNavigationQueryService)
179+
IPublishedContent? c = rootContent.DescendantsOrSelf(_variationContextAccessor, _contentCache, _documentNavigationQueryService, _publishStatusQueryService)
156180
.FirstOrDefault(x => IsMatch(x, test1, test2));
157181
if (c != null)
158182
{

src/Umbraco.Core/Routing/UrlProvider.cs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,48 @@ public class UrlProvider : IPublishedUrlProvider
2727
/// <param name="variationContextAccessor">The current variation accessor.</param>
2828
/// <param name="contentCache">The content cache.</param>
2929
/// <param name="navigationQueryService">The query service for the in-memory navigation structure.</param>
30+
/// <param name="publishStatusQueryService">The publish status query service, to query if a given content is published in a given culture.</param>
3031
public UrlProvider(
3132
IUmbracoContextAccessor umbracoContextAccessor,
3233
IOptions<WebRoutingSettings> routingSettings,
3334
UrlProviderCollection urlProviders,
3435
MediaUrlProviderCollection mediaUrlProviders,
3536
IVariationContextAccessor variationContextAccessor,
3637
IPublishedContentCache contentCache,
37-
IDocumentNavigationQueryService navigationQueryService)
38+
IDocumentNavigationQueryService navigationQueryService,
39+
IPublishStatusQueryService publishStatusQueryService)
3840
{
3941
_umbracoContextAccessor = umbracoContextAccessor ?? throw new ArgumentNullException(nameof(umbracoContextAccessor));
4042
_urlProviders = urlProviders;
4143
_mediaUrlProviders = mediaUrlProviders;
4244
_variationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
4345
_contentCache = contentCache;
4446
_navigationQueryService = navigationQueryService;
47+
_publishStatusQueryService = publishStatusQueryService;
4548
Mode = routingSettings.Value.UrlProviderMode;
4649
}
4750

51+
[Obsolete("Use the constructor that takes all parameters. Scheduled for removal in V17.")]
52+
public UrlProvider(
53+
IUmbracoContextAccessor umbracoContextAccessor,
54+
IOptions<WebRoutingSettings> routingSettings,
55+
UrlProviderCollection urlProviders,
56+
MediaUrlProviderCollection mediaUrlProviders,
57+
IVariationContextAccessor variationContextAccessor,
58+
IPublishedContentCache contentCache,
59+
IDocumentNavigationQueryService navigationQueryService)
60+
: this(
61+
umbracoContextAccessor,
62+
routingSettings,
63+
urlProviders,
64+
mediaUrlProviders,
65+
variationContextAccessor,
66+
contentCache,
67+
navigationQueryService,
68+
StaticServiceProvider.Instance.GetRequiredService<IPublishStatusQueryService>())
69+
{
70+
}
71+
4872
[Obsolete("Use the constructor that takes all parameters. Scheduled for removal in V17.")]
4973
public UrlProvider(
5074
IUmbracoContextAccessor umbracoContextAccessor,
@@ -59,7 +83,8 @@ public UrlProvider(
5983
mediaUrlProviders,
6084
variationContextAccessor,
6185
StaticServiceProvider.Instance.GetRequiredService<IPublishedContentCache>(),
62-
StaticServiceProvider.Instance.GetRequiredService<IDocumentNavigationQueryService>())
86+
StaticServiceProvider.Instance.GetRequiredService<IDocumentNavigationQueryService>(),
87+
StaticServiceProvider.Instance.GetRequiredService<IPublishStatusQueryService>())
6388
{
6489
}
6590

@@ -69,6 +94,7 @@ public UrlProvider(
6994
private readonly IVariationContextAccessor _variationContextAccessor;
7095
private readonly IPublishedContentCache _contentCache;
7196
private readonly IDocumentNavigationQueryService _navigationQueryService;
97+
private readonly IPublishStatusQueryService _publishStatusQueryService;
7298

7399
/// <summary>
74100
/// Gets or sets the provider URL mode.
@@ -147,7 +173,7 @@ public string GetUrl(IPublishedContent? content, UrlMode mode = UrlMode.Default,
147173
// be nice with tests, assume things can be null, ultimately fall back to invariant
148174
// (but only for variant content of course)
149175
// We need to check all ancestors because urls are variant even for invariant content, if an ancestor is variant.
150-
if (culture == null && content.AncestorsOrSelf(_contentCache, _navigationQueryService).Any(x => x.ContentType.VariesByCulture()))
176+
if (culture == null && content.AncestorsOrSelf(_variationContextAccessor, _contentCache, _navigationQueryService, _publishStatusQueryService).Any(x => x.ContentType.VariesByCulture()))
151177
{
152178
culture = _variationContextAccessor?.VariationContext?.Culture ?? string.Empty;
153179
}

src/Umbraco.Web.Common/Extensions/FriendlyPublishedContentExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ public static bool HasValue(
243243
/// set to 1.
244244
/// </remarks>
245245
public static IPublishedContent Root(this IPublishedContent content)
246-
=> content.Root(GetPublishedCache(content), GetNavigationQueryService(content));
246+
=> content.Root(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), PublishStatusQueryService);
247247

248248
/// <summary>
249249
/// Gets the root content (ancestor or self at level 1) for the specified <paramref name="content" /> if it's of the
@@ -262,7 +262,7 @@ public static IPublishedContent Root(this IPublishedContent content)
262262
/// </remarks>
263263
public static T? Root<T>(this IPublishedContent content)
264264
where T : class, IPublishedContent
265-
=> content.Root<T>(GetPublishedCache(content), GetNavigationQueryService(content));
265+
=> content.Root<T>(VariationContextAccessor, GetPublishedCache(content), GetNavigationQueryService(content), PublishStatusQueryService);
266266

267267
/// <summary>
268268
/// Gets the parent of the content item.

tests/Umbraco.Tests.UnitTests/AutoFixture/Customizations/UmbracoCustomizations.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Umbraco.Cms.Core.Configuration;
1212
using Umbraco.Cms.Core.Configuration.Models;
1313
using Umbraco.Cms.Core.Hosting;
14+
using Umbraco.Cms.Core.Routing;
1415
using Umbraco.Cms.Core.Security;
1516
using Umbraco.Cms.Core.Services;
1617
using Umbraco.Cms.Infrastructure.Install;
@@ -34,7 +35,8 @@ public void Customize(IFixture fixture)
3435
.Customize(new ConstructorCustomization(typeof(DatabaseSchemaCreatorFactory), new GreedyConstructorQuery()))
3536
.Customize(new ConstructorCustomization(typeof(InstallHelper), new GreedyConstructorQuery()))
3637
.Customize(new ConstructorCustomization(typeof(DatabaseBuilder), new GreedyConstructorQuery()))
37-
.Customize(new ConstructorCustomization(typeof(ContentVersionService), new GreedyConstructorQuery()));
38+
.Customize(new ConstructorCustomization(typeof(ContentVersionService), new GreedyConstructorQuery()))
39+
.Customize(new ConstructorCustomization(typeof(ContentFinderByUrlAlias), new GreedyConstructorQuery()));
3840

3941
// When requesting an IUserStore ensure we actually uses a IUserLockoutStore
4042
fixture.Customize<IUserStore<BackOfficeIdentityUser>>(cc =>

0 commit comments

Comments
 (0)