Avoid hybrid cache usage when traversing unpublished ancestors in a published context (non preview) (#19137)

* Filter Available should not return items without published ancestors when not in preview

* Update unittests mocks

* Internal documentation and minor code tidy.

* Tidied up integration tests and added new tests for the added method.

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
Sven Geusens
2025-04-24 21:07:40 +02:00
committed by GitHub
parent ef9a6e1821
commit ba0dcfa773
11 changed files with 371 additions and 236 deletions

View File

@@ -1,206 +0,0 @@
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Navigation;
using Umbraco.Cms.Core.Sync;
using Umbraco.Cms.Tests.Common.Builders;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services;
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Logger = UmbracoTestOptions.Logger.Mock)]
internal sealed class PublishStatusServiceTest : UmbracoIntegrationTestWithContent
{
protected IPublishStatusQueryService PublishStatusQueryService => GetRequiredService<IPublishStatusQueryService>();
private const string DefaultCulture = "en-US";
protected override void CustomTestSetup(IUmbracoBuilder builder)
{
builder.Services.AddUnique<IServerMessenger, ScopedRepositoryTests.LocalServerMessenger>();
builder.AddNotificationHandler<ContentTreeChangeNotification, ContentTreeChangeDistributedCacheNotificationHandler>();
}
[Test]
public async Task InitializeAsync_loads_from_db()
{
var randomCulture = "da-DK";
var sut = new PublishStatusService(
GetRequiredService<ILogger<PublishStatusService>>(),
GetRequiredService<IPublishStatusRepository>(),
GetRequiredService<ICoreScopeProvider>());
Assert.Multiple(() =>
{
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage3.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, randomCulture));
});
// Act
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
await sut.InitializeAsync(CancellationToken.None);
Assert.Multiple(() =>
{
Assert.IsTrue(publishResults.All(x=>x.Result == PublishResultType.SuccessPublish));
Assert.IsTrue(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage3.Key, randomCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, randomCulture));
});
}
[Test]
public async Task AddOrUpdateStatusWithDescendantsAsync()
{
var randomCulture = "da-DK";
var sut = new PublishStatusService(
GetRequiredService<ILogger<PublishStatusService>>(),
GetRequiredService<IPublishStatusRepository>(),
GetRequiredService<ICoreScopeProvider>(),
GetRequiredService<ILanguageService>()
);
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
// Act
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
await sut.AddOrUpdateStatusWithDescendantsAsync(Textpage.Key, CancellationToken.None);
Assert.IsTrue(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage.Key, DefaultCulture)); // Updated due to being an descendant
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, randomCulture)); // Do not exist
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, randomCulture)); // Do not exist
}
[Test]
public async Task AddOrUpdateStatusAsync()
{
var randomCulture = "da-DK";
var sut = new PublishStatusService(
GetRequiredService<ILogger<PublishStatusService>>(),
GetRequiredService<IPublishStatusRepository>(),
GetRequiredService<ICoreScopeProvider>(),
GetRequiredService<ILanguageService>());
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
// Act
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
await sut.AddOrUpdateStatusAsync(Textpage.Key, CancellationToken.None);
Assert.IsTrue(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, DefaultCulture)); // Not updated
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, randomCulture)); // Do not exist
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, randomCulture)); // Do not exist
}
[Test]
public void When_Nothing_is_publised_all_return_false()
{
var randomCulture = "da-DK";
Assert.Multiple(() =>
{
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, randomCulture));
});
}
[Test]
public void Unpublish_leads_to_unpublised_in_this_service()
{
var grandchild = ContentBuilder.CreateSimpleContent(ContentType, "Grandchild", Subpage2.Id);
var contentSchedule = ContentScheduleCollection.CreateWithEntry(DateTime.UtcNow.AddMinutes(-5), null);
ContentService.Save(grandchild, -1, contentSchedule);
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
var randomCulture = "da-DK";
var subPage2FromDB = ContentService.GetById(Subpage2.Key);
var publishResult = ContentService.Unpublish(subPage2FromDB);
Assert.Multiple(() =>
{
Assert.IsTrue(publishResults.All(x=>x.Result == PublishResultType.SuccessPublish));
Assert.IsTrue(publishResult.Success);
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(grandchild.Key, DefaultCulture)); // grandchild is still published, but it will not be routable
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(grandchild.Key, randomCulture));
});
}
[Test]
public void When_Branch_is_publised_default_language_return_true()
{
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
var randomCulture = "da-DK";
Assert.Multiple(() =>
{
Assert.IsTrue(publishResults.All(x=>x.Result == PublishResultType.SuccessPublish));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, randomCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, randomCulture));
});
}
}

View File

@@ -0,0 +1,113 @@
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Navigation;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services;
internal sealed partial class PublishStatusServiceTests
{
[Test]
public async Task InitializeAsync_Loads_From_Database()
{
var sut = CreatePublishedStatusService();
Assert.Multiple(() =>
{
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage3.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, UnusedCulture));
});
// Act
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
await sut.InitializeAsync(CancellationToken.None);
Assert.Multiple(() =>
{
Assert.IsTrue(publishResults.All(x => x.Result == PublishResultType.SuccessPublish));
Assert.IsTrue(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage3.Key, UnusedCulture));
Assert.IsFalse(sut.IsDocumentPublished(Trashed.Key, UnusedCulture));
});
}
[Test]
public async Task AddOrUpdateStatusWithDescendantsAsync_Updates_Document_Path_Published_Status()
{
var sut = new PublishStatusService(
GetRequiredService<ILogger<PublishStatusService>>(),
GetRequiredService<IPublishStatusRepository>(),
GetRequiredService<ICoreScopeProvider>(),
GetRequiredService<ILanguageService>(),
GetRequiredService<IDocumentNavigationQueryService>());
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
// Act
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
await sut.AddOrUpdateStatusWithDescendantsAsync(Textpage.Key, CancellationToken.None);
Assert.IsTrue(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(sut.IsDocumentPublished(Subpage.Key, DefaultCulture)); // Updated due to being an descendant
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, UnusedCulture)); // Do not exist
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, UnusedCulture)); // Do not exist
}
[Test]
public async Task AddOrUpdateStatusAsync_Updates_Document_Published_Status()
{
var sut = new PublishStatusService(
GetRequiredService<ILogger<PublishStatusService>>(),
GetRequiredService<IPublishStatusRepository>(),
GetRequiredService<ICoreScopeProvider>(),
GetRequiredService<ILanguageService>(),
GetRequiredService<IDocumentNavigationQueryService>());
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
// Act
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
await sut.AddOrUpdateStatusAsync(Textpage.Key, CancellationToken.None);
Assert.IsTrue(sut.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, DefaultCulture)); // Not updated
Assert.IsFalse(sut.IsDocumentPublished(Textpage.Key, UnusedCulture)); // Do not exist
Assert.IsFalse(sut.IsDocumentPublished(Subpage.Key, UnusedCulture)); // Do not exist
}
private PublishStatusService CreatePublishedStatusService()
=> new(
GetRequiredService<ILogger<PublishStatusService>>(),
GetRequiredService<IPublishStatusRepository>(),
GetRequiredService<ICoreScopeProvider>(),
GetRequiredService<ILanguageService>(),
GetRequiredService<IDocumentNavigationQueryService>());
}

View File

@@ -0,0 +1,129 @@
using NUnit.Framework;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Navigation;
using Umbraco.Cms.Tests.Common.Builders;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services;
internal sealed partial class PublishStatusServiceTests
{
private IPublishStatusQueryService PublishStatusQueryService => GetRequiredService<IPublishStatusQueryService>();
[Test]
public void When_Nothing_Is_Publised_All_Documents_Have_Unpublished_Status()
{
Assert.Multiple(() =>
{
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Textpage.Key));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage.Key));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage2.Key));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage3.Key));
});
}
[Test]
public void Unpublish_Updates_Document_Path_Published_Status()
{
var grandchild = ContentBuilder.CreateSimpleContent(ContentType, "Grandchild", Subpage2.Id);
var contentSchedule = ContentScheduleCollection.CreateWithEntry(DateTime.UtcNow.AddMinutes(-5), null);
ContentService.Save(grandchild, -1, contentSchedule);
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
var subPage2FromDB = ContentService.GetById(Subpage2.Key);
var publishResult = ContentService.Unpublish(subPage2FromDB);
Assert.Multiple(() =>
{
Assert.IsTrue(publishResults.All(x => x.Result == PublishResultType.SuccessPublish));
Assert.IsTrue(publishResult.Success);
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(grandchild.Key, DefaultCulture)); // grandchild is still published, but it will not be routable
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(grandchild.Key, UnusedCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Textpage.Key));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage2.Key));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(grandchild.Key));
});
}
[Test]
public void Publish_Branch_Updates_Document_Path_Published_Status()
{
var publishResults = ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
Assert.Multiple(() =>
{
Assert.IsTrue(publishResults.All(x => x.Result == PublishResultType.SuccessPublish));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage2.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage3.Key, UnusedCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Trashed.Key, UnusedCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Textpage.Key));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage.Key));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage2.Key));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublishedInAnyCulture(Subpage3.Key));
Assert.IsTrue(PublishStatusQueryService.HasPublishedAncestorPath(Textpage.Key));
Assert.IsTrue(PublishStatusQueryService.HasPublishedAncestorPath(Subpage.Key));
});
}
[Test]
public void Published_Document_With_UnPublished_Parent_Has_Unpublished_Path()
{
Assert.Multiple(() =>
{
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
});
ContentService.PublishBranch(Textpage, PublishBranchFilter.IncludeUnpublished, ["*"]);
Assert.Multiple(() =>
{
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
});
ContentService.Unpublish(Textpage);
// Unpublish the root item - the sub page will still be published but it won't have a published path.
Assert.Multiple(() =>
{
Assert.IsFalse(PublishStatusQueryService.IsDocumentPublished(Textpage.Key, DefaultCulture));
Assert.IsTrue(PublishStatusQueryService.IsDocumentPublished(Subpage.Key, DefaultCulture));
Assert.IsFalse(PublishStatusQueryService.HasPublishedAncestorPath(Subpage.Key));
});
}
}

View File

@@ -0,0 +1,30 @@
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Navigation;
using Umbraco.Cms.Core.Sync;
using Umbraco.Cms.Tests.Common.Builders;
using Umbraco.Cms.Tests.Common.Testing;
using Umbraco.Cms.Tests.Integration.Testing;
using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping;
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services;
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, Logger = UmbracoTestOptions.Logger.Mock)]
internal sealed partial class PublishStatusServiceTests : UmbracoIntegrationTestWithContent
{
private const string DefaultCulture = "en-US";
private const string UnusedCulture = "da-DK";
protected override void CustomTestSetup(IUmbracoBuilder builder)
{
builder.Services.AddUnique<IServerMessenger, ScopedRepositoryTests.LocalServerMessenger>();
builder.AddNotificationHandler<ContentTreeChangeNotification, ContentTreeChangeDistributedCacheNotificationHandler>();
}
}

View File

@@ -274,6 +274,12 @@
<Compile Update="Umbraco.Core\Services\PublishedUrlInfoProviderTests.cs">
<DependentUpon>PublishedUrlInfoProviderTestsBase.cs</DependentUpon>
</Compile>
<Compile Update="Umbraco.Core\Services\PublishStatusServiceTests.Management.cs">
<DependentUpon>PublishStatusServiceTests.cs</DependentUpon>
</Compile>
<Compile Update="Umbraco.Core\Services\PublishStatusServiceTests.Query.cs">
<DependentUpon>PublishStatusServiceTests.cs</DependentUpon>
</Compile>
<Compile Update="ManagementApi\Services\UserStartNodeEntitiesServiceTests.ChildUserAccessEntities.cs">
<DependentUpon>UserStartNodeEntitiesServiceTests.cs</DependentUpon>
</Compile>

View File

@@ -65,6 +65,9 @@ public class DeliveryApiTests
publishStatusQueryService
.Setup(x => x.IsDocumentPublished(It.IsAny<Guid>(), It.IsAny<string>()))
.Returns(true);
publishStatusQueryService
.Setup(x => x.HasPublishedAncestorPath(It.IsAny<Guid>()))
.Returns(true);
PublishStatusQueryService = publishStatusQueryService.Object;
}

View File

@@ -329,6 +329,9 @@ public partial class PublishedContentStatusFilteringServiceTests
.TryGetValue(key, out var item)
&& idIsPublished(item.Id)
&& (item.ContentType.VariesByCulture() is false || item.Cultures.ContainsKey(culture)));
publishStatusQueryService
.Setup(s => s.HasPublishedAncestorPath(It.IsAny<Guid>()))
.Returns(true);
return publishStatusQueryService.Object;
}