Copy and move API for content and media (#14040)
* Copy and Move API for Content and Media * Update OpenAPI JSON schema * Update OpenApi JSON file after merge * Rename key to id --------- Co-authored-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
@@ -0,0 +1,248 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
|
||||
|
||||
public partial class ContentEditingServiceTests
|
||||
{
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Copy_To_Root(bool allowedAtRoot)
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
contentType.AllowedAsRoot = allowedAtRoot;
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(child.Key, Constants.System.RootKey, false, false, Constants.Security.SuperUserKey);
|
||||
|
||||
if (allowedAtRoot)
|
||||
{
|
||||
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? copiedContent)
|
||||
{
|
||||
Assert.IsNotNull(copiedContent);
|
||||
Assert.AreEqual(Constants.System.Root, copiedContent.ParentId);
|
||||
Assert.IsTrue(copiedContent.HasIdentity);
|
||||
Assert.AreNotEqual(child.Id, copiedContent.Id);
|
||||
Assert.AreNotEqual(child.Key, copiedContent.Key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.NotAllowed, result.Status);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Copy_To_Another_Parent(bool allowedAtParent)
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root1, IContent child1) = await CreateRootAndChildAsync(contentType, "Root 1", "Child 1");
|
||||
(IContent root2, IContent child2) = await CreateRootAndChildAsync(contentType, "Root 2", "Child 2");
|
||||
|
||||
if (allowedAtParent is false)
|
||||
{
|
||||
contentType.AllowedContentTypes = Enumerable.Empty<ContentTypeSort>();
|
||||
}
|
||||
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(child1.Key, root2.Key, false, false, Constants.Security.SuperUserKey);
|
||||
|
||||
if (allowedAtParent)
|
||||
{
|
||||
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? copiedContent)
|
||||
{
|
||||
Assert.IsNotNull(copiedContent);
|
||||
Assert.AreEqual(root2.Id, copiedContent.ParentId);
|
||||
Assert.IsTrue(copiedContent.HasIdentity);
|
||||
Assert.AreNotEqual(child1.Id, copiedContent.Id);
|
||||
Assert.AreNotEqual(child1.Key, copiedContent.Key);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.NotAllowed, result.Status);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Copy_Entire_Structure(bool includeDescendants)
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root1, IContent child1) = await CreateRootAndChildAsync(contentType, "Root 1", "Child 1");
|
||||
(IContent root2, IContent child2) = await CreateRootAndChildAsync(contentType, "Root 2", "Child 2");
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(root1.Key, root2.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(root2.Id, copiedRoot.ParentId);
|
||||
Assert.AreNotEqual(root1.Id, copiedRoot.Id);
|
||||
Assert.AreNotEqual(root1.Key, copiedRoot.Key);
|
||||
Assert.AreEqual(root1.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(child1.Id, copiedChild.Id);
|
||||
Assert.AreNotEqual(child1.Key, copiedChild.Key);
|
||||
Assert.AreEqual(child1.Name, copiedChild.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.AreEqual(0, copiedChildren.Length);
|
||||
Assert.AreEqual(0, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Copy_To_Existing_Parent()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(child.Key, root.Key, false, false, 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? copiedContent)
|
||||
{
|
||||
Assert.IsNotNull(copiedContent);
|
||||
Assert.AreEqual(root.Id, copiedContent.ParentId);
|
||||
Assert.IsTrue(copiedContent.HasIdentity);
|
||||
Assert.AreNotEqual(child.Key, copiedContent.Key);
|
||||
Assert.AreNotEqual(child.Name, copiedContent.Name);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Copy_Beneath_Self(bool includeDescendants)
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(root.Key, child.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(child.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()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(child.Key, root.Key, true, false, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
|
||||
var relationService = GetRequiredService<IRelationService>();
|
||||
var relations = relationService.GetByParentId(child.Id)!.ToArray();
|
||||
Assert.AreEqual(1, relations.Length);
|
||||
Assert.AreEqual(result.Result!.Id, relations.First().ChildId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Copy_Non_Existing_Content()
|
||||
{
|
||||
var result = await ContentEditingService.CopyAsync(Guid.NewGuid(), Constants.System.RootKey, false, false, Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.NotFound, result.Status);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Copy_To_Non_Existing_Parent()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(child.Key, Guid.NewGuid(), false, false, Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.ParentNotFound, result.Status);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Copy_To_Trashed_Parent()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root1, IContent child1) = await CreateRootAndChildAsync(contentType);
|
||||
(IContent root2, IContent child2) = await CreateRootAndChildAsync(contentType);
|
||||
await ContentEditingService.MoveToRecycleBinAsync(root1.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
var result = await ContentEditingService.CopyAsync(root2.Key, root1.Key, false, false, Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.InTrash, result.Status);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public partial class ContentEditingServiceTests
|
||||
{
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Create_At_Root(bool allowedAtRoot)
|
||||
public async Task Can_Create_At_Root(bool allowedAtRoot)
|
||||
{
|
||||
var template = TemplateBuilder.CreateTextPageTemplate();
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
@@ -64,7 +64,7 @@ public partial class ContentEditingServiceTests
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Create_As_Child(bool allowedAsChild)
|
||||
public async Task Can_Create_As_Child(bool allowedAsChild)
|
||||
{
|
||||
var template = TemplateBuilder.CreateTextPageTemplate();
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
@@ -427,4 +427,36 @@ public partial class ContentEditingServiceTests
|
||||
Assert.AreEqual(ContentEditingOperationStatus.PropertyTypeNotFound, result.Status);
|
||||
Assert.IsNull(result.Result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Create_Under_Trashed_Parent()
|
||||
{
|
||||
var contentType = ContentTypeBuilder.CreateBasicContentType();
|
||||
contentType.AllowedAsRoot = true;
|
||||
contentType.AllowedContentTypes = new[]
|
||||
{
|
||||
new ContentTypeSort(new Lazy<int>(() => contentType.Id), contentType.Key, 1, contentType.Alias)
|
||||
};
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var rootKey = (await ContentEditingService.CreateAsync(
|
||||
new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key, InvariantName = "Root", ParentKey = Constants.System.RootKey
|
||||
},
|
||||
Constants.Security.SuperUserKey)).Result.Key;
|
||||
|
||||
await ContentEditingService.MoveToRecycleBinAsync(rootKey, Constants.Security.SuperUserKey);
|
||||
|
||||
var result = await ContentEditingService.CreateAsync(
|
||||
new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key, InvariantName = "Child", ParentKey = rootKey,
|
||||
},
|
||||
Constants.Security.SuperUserKey);
|
||||
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.InTrash, result.Status);
|
||||
Assert.IsNull(result.Result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
|
||||
|
||||
public partial class ContentEditingServiceTests
|
||||
{
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Move_To_Root(bool allowedAtRoot)
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
contentType.AllowedAsRoot = allowedAtRoot;
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(child.Key, Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
|
||||
if (allowedAtRoot)
|
||||
{
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
VerifyMove(result.Result);
|
||||
|
||||
// re-get and re-test
|
||||
VerifyMove(await ContentEditingService.GetAsync(result.Result!.Key));
|
||||
|
||||
void VerifyMove(IContent? movedContent)
|
||||
{
|
||||
Assert.IsNotNull(movedContent);
|
||||
Assert.AreEqual(Constants.System.Root, movedContent.ParentId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.NotAllowed, result.Status);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public async Task Can_Move_To_Another_Parent(bool allowedAtParent)
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root1, IContent child1) = await CreateRootAndChildAsync(contentType, "Root 1", "Child 1");
|
||||
(IContent root2, IContent child2) = await CreateRootAndChildAsync(contentType, "Root 2", "Child 2");
|
||||
|
||||
if (allowedAtParent is false)
|
||||
{
|
||||
contentType.AllowedContentTypes = Enumerable.Empty<ContentTypeSort>();
|
||||
}
|
||||
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(child1.Key, root2.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
if (allowedAtParent)
|
||||
{
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
VerifyMove(result.Result);
|
||||
|
||||
// re-get and re-test
|
||||
VerifyMove(await ContentEditingService.GetAsync(result.Result!.Key));
|
||||
|
||||
void VerifyMove(IContent? movedContent)
|
||||
{
|
||||
Assert.IsNotNull(movedContent);
|
||||
Assert.AreEqual(root2.Id, movedContent.ParentId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.NotAllowed, result.Status);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Move_Entire_Structure()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root1, IContent child1) = await CreateRootAndChildAsync(contentType, "Root 1", "Child 1");
|
||||
(IContent root2, IContent child2) = await CreateRootAndChildAsync(contentType, "Root 2", "Child 2");
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(root1.Key, root2.Key, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
|
||||
VerifyMove(result.Result);
|
||||
|
||||
// re-get and re-test
|
||||
VerifyMove(await ContentEditingService.GetAsync(result.Result!.Key));
|
||||
|
||||
child1 = await ContentEditingService.GetAsync(child1.Key);
|
||||
Assert.IsNotNull(child1);
|
||||
var ancestorIds = child1.GetAncestorIds()!.ToArray();
|
||||
Assert.AreEqual(2, ancestorIds.Length);
|
||||
Assert.AreEqual(root2.Id, ancestorIds.First());
|
||||
Assert.AreEqual(root1.Id, ancestorIds.Last());
|
||||
|
||||
void VerifyMove(IContent? movedContent)
|
||||
{
|
||||
Assert.IsNotNull(movedContent);
|
||||
Assert.AreEqual(root2.Id, movedContent.ParentId);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Move_To_Existing_Parent()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(child.Key, root.Key, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
|
||||
VerifyMove(result.Result);
|
||||
|
||||
// re-get and re-test
|
||||
VerifyMove(await ContentEditingService.GetAsync(result.Result!.Key));
|
||||
|
||||
void VerifyMove(IContent? movedContent)
|
||||
{
|
||||
Assert.IsNotNull(movedContent);
|
||||
Assert.AreEqual(root.Id, movedContent.ParentId);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Move_From_Root_To_Root()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(root.Key, Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status);
|
||||
|
||||
VerifyMove(result.Result);
|
||||
|
||||
// re-get and re-test
|
||||
VerifyMove(await ContentEditingService.GetAsync(result.Result!.Key));
|
||||
|
||||
void VerifyMove(IContent? movedContent)
|
||||
{
|
||||
Assert.IsNotNull(movedContent);
|
||||
Assert.AreEqual(Constants.System.Root, movedContent.ParentId);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Move_Non_Existing_Content()
|
||||
{
|
||||
var result = await ContentEditingService.MoveAsync(Guid.NewGuid(), Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.NotFound, result.Status);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Move_To_Non_Existing_Parent()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(child.Key, Guid.NewGuid(), Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.ParentNotFound, result.Status);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Move_To_Trashed_Parent()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root1, IContent child1) = await CreateRootAndChildAsync(contentType);
|
||||
(IContent root2, IContent child2) = await CreateRootAndChildAsync(contentType);
|
||||
await ContentEditingService.MoveToRecycleBinAsync(root1.Key, Constants.Security.SuperUserKey);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(root2.Key, root1.Key, Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.InTrash, result.Status);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Cannot_Move_Beneath_Self()
|
||||
{
|
||||
var contentType = await CreateTextPageContentTypeAsync();
|
||||
(IContent root, IContent child) = await CreateRootAndChildAsync(contentType);
|
||||
|
||||
var result = await ContentEditingService.MoveAsync(root.Key, child.Key, Constants.Security.SuperUserKey);
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreEqual(ContentEditingOperationStatus.ParentInvalid, result.Status);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
@@ -22,6 +23,9 @@ public partial class ContentEditingServiceTests : UmbracoIntegrationTestWithCont
|
||||
[SetUp]
|
||||
public void Setup() => ContentRepositoryBase.ThrowOnWarning = true;
|
||||
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder) =>
|
||||
builder.AddNotificationHandler<ContentCopiedNotification, RelateOnCopyNotificationHandler>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private ILanguageService LanguageService => GetRequiredService<ILanguageService>();
|
||||
@@ -155,4 +159,42 @@ public partial class ContentEditingServiceTests : UmbracoIntegrationTestWithCont
|
||||
Assert.IsTrue(result.Success);
|
||||
return result.Result!;
|
||||
}
|
||||
|
||||
private async Task<IContentType> CreateTextPageContentTypeAsync()
|
||||
{
|
||||
var template = TemplateBuilder.CreateTextPageTemplate();
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id);
|
||||
contentType.AllowedAsRoot = true;
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private async Task<(IContent root, IContent child)> CreateRootAndChildAsync(IContentType contentType, string rootName = "The Root", string childName = "The Child")
|
||||
{
|
||||
var createModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = rootName
|
||||
};
|
||||
|
||||
var root = (await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey)).Result!;
|
||||
|
||||
contentType.AllowedContentTypes = new List<ContentTypeSort>
|
||||
{
|
||||
new (new Lazy<int>(() => contentType.Id), contentType.Key, 1, contentType.Alias)
|
||||
};
|
||||
ContentTypeService.Save(contentType);
|
||||
|
||||
createModel.ParentKey = root.Key;
|
||||
createModel.InvariantName = childName;
|
||||
|
||||
var child = (await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey)).Result!;
|
||||
Assert.AreEqual(root.Id, child.ParentId);
|
||||
|
||||
return (root, child);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user