Merge branch 'v14/dev' into v15/dev

# Conflicts:
#	Directory.Packages.props
#	src/Umbraco.Cms.Api.Common/DependencyInjection/UmbracoBuilderAuthExtensions.cs
#	src/Umbraco.Cms.Api.Delivery/DependencyInjection/UmbracoBuilderExtensions.cs
#	src/Umbraco.Cms.Api.Delivery/Querying/Selectors/AncestorsSelector.cs
#	src/Umbraco.Cms.Api.Management/OpenApi.json
#	src/Umbraco.Infrastructure/Examine/ExamineIndexRebuilder.cs
#	src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs
#	src/Umbraco.PublishedCache.NuCache/ContentStore.cs
#	tests/Directory.Packages.props
This commit is contained in:
Sven Geusens
2025-01-21 10:17:46 +01:00
40 changed files with 11506 additions and 34 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -198,6 +198,48 @@ public partial class ContentEditingServiceTests
}
}
[TestCase(true)]
[TestCase(false)]
public async Task Can_Copy_Onto_Self(bool includeDescendants)
{
var contentType = await CreateTextPageContentTypeAsync();
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
var result = await ContentEditingService.CopyAsync(root.Key, root.Key, false, includeDescendants, Constants.Security.SuperUserKey);
Assert.IsTrue(result.Success);
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
VerifyCopy(result.Result);
// re-get and re-test
VerifyCopy(await ContentEditingService.GetAsync(result.Result!.Key));
void VerifyCopy(IContent? copiedRoot)
{
Assert.IsNotNull(copiedRoot);
Assert.AreEqual(root.Id, copiedRoot.ParentId);
Assert.IsTrue(copiedRoot.HasIdentity);
Assert.AreNotEqual(root.Key, copiedRoot.Key);
Assert.AreEqual(root.Name, copiedRoot.Name);
var copiedChildren = ContentService.GetPagedChildren(copiedRoot.Id, 0, 100, out var total).ToArray();
if (includeDescendants)
{
Assert.AreEqual(1, copiedChildren.Length);
Assert.AreEqual(1, total);
var copiedChild = copiedChildren.First();
Assert.AreNotEqual(child.Id, copiedChild.Id);
Assert.AreNotEqual(child.Key, copiedChild.Key);
Assert.AreEqual(child.Name, copiedChild.Name);
}
else
{
Assert.AreEqual(0, copiedChildren.Length);
Assert.AreEqual(0, total);
}
}
}
[Test]
public async Task Can_Relate_Copy_To_Original()
{

View File

@@ -54,7 +54,8 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
.AddNotificationHandler<ContentPublishingNotification, ContentNotificationHandler>()
.AddNotificationHandler<ContentPublishedNotification, ContentNotificationHandler>()
.AddNotificationHandler<ContentUnpublishingNotification, ContentNotificationHandler>()
.AddNotificationHandler<ContentUnpublishedNotification, ContentNotificationHandler>();
.AddNotificationHandler<ContentUnpublishedNotification, ContentNotificationHandler>()
.AddNotificationHandler<ContentTreeChangeNotification, ContentNotificationHandler>();
private void CreateTestData()
{
@@ -176,6 +177,69 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
}
}
[Test]
public void Publishing_Invariant()
{
IContent document = new Content("content", -1, _contentType);
ContentService.Save(document);
var treeChangeWasCalled = false;
ContentNotificationHandler.TreeChange += notification =>
{
var change = notification.Changes.FirstOrDefault();
var publishedCultures = change?.PublishedCultures?.ToArray();
Assert.IsNotNull(publishedCultures);
Assert.AreEqual(1, publishedCultures.Length);
Assert.IsTrue(publishedCultures.InvariantContains("*"));
Assert.IsNull(change.UnpublishedCultures);
treeChangeWasCalled = true;
};
try
{
ContentService.Publish(document, ["*"]);
Assert.IsTrue(treeChangeWasCalled);
}
finally
{
ContentNotificationHandler.TreeChange = null;
}
}
[Test]
public void Unpublishing_Invariant()
{
IContent document = new Content("content", -1, _contentType);
ContentService.Save(document);
ContentService.Publish(document, ["*"]);
var treeChangeWasCalled = false;
ContentNotificationHandler.TreeChange += notification =>
{
var change = notification.Changes.FirstOrDefault();
Assert.IsNull(change?.PublishedCultures);
var unpublishedCultures = change?.UnpublishedCultures?.ToArray();
Assert.IsNotNull(unpublishedCultures);
Assert.AreEqual(1, unpublishedCultures.Length);
Assert.IsTrue(unpublishedCultures.InvariantContains("*"));
treeChangeWasCalled = true;
};
try
{
ContentService.Unpublish(document);
Assert.IsTrue(treeChangeWasCalled);
}
finally
{
ContentNotificationHandler.TreeChange = null;
}
}
[Test]
public async Task Publishing_Culture()
{
@@ -202,6 +266,7 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
var publishingWasCalled = false;
var publishedWasCalled = false;
var treeChangeWasCalled = false;
ContentNotificationHandler.PublishingContent += notification =>
{
@@ -227,16 +292,30 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
publishedWasCalled = true;
};
ContentNotificationHandler.TreeChange += notification =>
{
var change = notification.Changes.FirstOrDefault();
var publishedCultures = change?.PublishedCultures?.ToArray();
Assert.IsNotNull(publishedCultures);
Assert.AreEqual(1, publishedCultures.Length);
Assert.IsTrue(publishedCultures.InvariantContains("fr-FR"));
Assert.IsNull(change.UnpublishedCultures);
treeChangeWasCalled = true;
};
try
{
ContentService.Publish(document, new[] { "fr-FR" });
Assert.IsTrue(publishingWasCalled);
Assert.IsTrue(publishedWasCalled);
Assert.IsTrue(treeChangeWasCalled);
}
finally
{
ContentNotificationHandler.PublishingContent = null;
ContentNotificationHandler.PublishedContent = null;
ContentNotificationHandler.TreeChange = null;
}
document = ContentService.GetById(document.Id);
@@ -399,6 +478,7 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
var publishingWasCalled = false;
var publishedWasCalled = false;
var treeChangeWasCalled = false;
// TODO: revisit this - it was migrated when removing static events, but the expected result seems illogic - why does this test bind to Published and not Unpublished?
@@ -432,16 +512,30 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
publishedWasCalled = true;
};
ContentNotificationHandler.TreeChange += notification =>
{
var change = notification.Changes.FirstOrDefault();
var unpublishedCultures = change?.UnpublishedCultures?.ToArray();
Assert.IsNotNull(unpublishedCultures);
Assert.AreEqual(1, unpublishedCultures.Length);
Assert.IsTrue(unpublishedCultures.InvariantContains("fr-FR"));
Assert.IsNull(change.PublishedCultures);
treeChangeWasCalled = true;
};
try
{
ContentService.CommitDocumentChanges(document);
Assert.IsTrue(publishingWasCalled);
Assert.IsTrue(publishedWasCalled);
Assert.IsTrue(treeChangeWasCalled);
}
finally
{
ContentNotificationHandler.PublishingContent = null;
ContentNotificationHandler.PublishedContent = null;
ContentNotificationHandler.TreeChange = null;
}
document = ContentService.GetById(document.Id);
@@ -456,7 +550,8 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
INotificationHandler<ContentPublishingNotification>,
INotificationHandler<ContentPublishedNotification>,
INotificationHandler<ContentUnpublishingNotification>,
INotificationHandler<ContentUnpublishedNotification>
INotificationHandler<ContentUnpublishedNotification>,
INotificationHandler<ContentTreeChangeNotification>
{
public static Action<ContentSavingNotification> SavingContent { get; set; }
@@ -470,6 +565,8 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
public static Action<ContentUnpublishedNotification> UnpublishedContent { get; set; }
public static Action<ContentTreeChangeNotification> TreeChange { get; set; }
public void Handle(ContentPublishedNotification notification) => PublishedContent?.Invoke(notification);
public void Handle(ContentPublishingNotification notification) => PublishingContent?.Invoke(notification);
@@ -480,5 +577,7 @@ public class ContentServiceNotificationTests : UmbracoIntegrationTest
public void Handle(ContentUnpublishedNotification notification) => UnpublishedContent?.Invoke(notification);
public void Handle(ContentUnpublishingNotification notification) => UnpublishingContent?.Invoke(notification);
public void Handle(ContentTreeChangeNotification notification) => TreeChange?.Invoke(notification);
}
}