From be16aa0663d052e1b636647435f44a1e68a957c7 Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com> Date: Thu, 4 Apr 2024 09:40:06 +0200 Subject: [PATCH] V14: Test new content blueprint editing service (#15970) * Fix wrong service name * Move tests to correct place and fix naming * Introducing a test base * Tests IContentBlueprintEditingService * Remove comment * Adding Assert.Multiple * More Assert.Multiple + Can_Create_With_Basic_Model() and Cannot_Create_When_Content_Type_Not_Found() --- .../Services/ContentEditingServiceTests.cs | 7 +- ...tentBlueprintEditingServiceTests.Create.cs | 287 ++++++++++++++++++ ...ntEditingServiceTests.CreateFromContent.cs | 140 +++++++++ ...tentBlueprintEditingServiceTests.Delete.cs | 39 +++ ...ContentBlueprintEditingServiceTests.Get.cs | 24 ++ ...tentBlueprintEditingServiceTests.Update.cs | 152 ++++++++++ .../ContentBlueprintEditingServiceTests.cs | 74 +++++ ...ntEditingServiceTests.MoveToRecycleBin.cs} | 0 .../Services/ContentEditingServiceTests.cs | 153 +--------- .../ContentEditingServiceTestsBase.cs | 153 ++++++++++ ...ontentPublishingServiceTests.Scheduling.cs | 2 - .../Umbraco.Tests.Integration.csproj | 30 +- 12 files changed, 900 insertions(+), 161 deletions(-) create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Create.cs create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.CreateFromContent.cs create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Delete.cs create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Get.cs create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Update.cs create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.cs rename tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/{ContentEditingServiceTests.MoveToRecyleBin.cs => ContentEditingServiceTests.MoveToRecycleBin.cs} (100%) create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTestsBase.cs diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentEditingServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentEditingServiceTests.cs index 13215ce87c..75100f8cea 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentEditingServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentEditingServiceTests.cs @@ -24,7 +24,8 @@ public class ContentEditingServiceTests : UmbracoIntegrationTestWithContent [TearDown] public void Teardown() => ContentRepositoryBase.ThrowOnWarning = false; - private IContentEditingService ContentTypeEditingService => GetRequiredService(); + private IContentEditingService ContentEditingService => GetRequiredService(); + private ILanguageService LanguageService => GetRequiredService(); [Test] @@ -69,7 +70,7 @@ public class ContentEditingServiceTests : UmbracoIntegrationTestWithContent } }; - await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); var content = ContentService.GetById(documentKey)!; @@ -86,7 +87,7 @@ public class ContentEditingServiceTests : UmbracoIntegrationTestWithContent } }; - await ContentTypeEditingService.UpdateAsync(content.Key, updateModel, Constants.Security.SuperUserKey); + await ContentEditingService.UpdateAsync(content.Key, updateModel, Constants.Security.SuperUserKey); var updatedContent = ContentService.GetById(documentKey)!; diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Create.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Create.cs new file mode 100644 index 0000000000..144c01948e --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Create.cs @@ -0,0 +1,287 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Services.OperationStatus; +using Umbraco.Cms.Tests.Common.Builders; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +public partial class ContentBlueprintEditingServiceTests +{ + [Test] + public async Task Can_Create_With_Basic_Model() + { + var contentType = CreateInvariantContentType(); + + var createModel = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + InvariantName = "Test Create Blueprint", + }; + + var result = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + }); + VerifyCreate(result.Result.Content); + + // re-get and re-test + VerifyCreate(await ContentBlueprintEditingService.GetAsync(result.Result.Content!.Key)); + + void VerifyCreate(IContent? createdBlueprint) + { + Assert.IsNotNull(createdBlueprint); + Assert.Multiple(() => + { + Assert.AreNotEqual(Guid.Empty, createdBlueprint.Key); + Assert.IsTrue(createdBlueprint.HasIdentity); + Assert.AreEqual("Test Create Blueprint", createdBlueprint.Name); + }); + } + + // ensures it's not found by normal content + var contentFound = await ContentEditingService.GetAsync(result.Result.Content!.Key); + Assert.IsNull(contentFound); + } + + [Test] + public async Task Can_Create_At_Root() + { + var contentType = CreateInvariantContentType(); + + var createModel = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var result = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + }); + VerifyCreate(result.Result.Content); + + // re-get and re-test + VerifyCreate(await ContentBlueprintEditingService.GetAsync(result.Result.Content!.Key)); + + void VerifyCreate(IContent? createdBlueprint) + { + Assert.IsNotNull(createdBlueprint); + Assert.Multiple(() => + { + Assert.AreNotEqual(Guid.Empty, createdBlueprint.Key); + Assert.IsTrue(createdBlueprint.HasIdentity); + Assert.AreEqual("Test Create Blueprint", createdBlueprint.Name); + Assert.AreEqual("The title value", createdBlueprint.GetValue("title")); + }); + } + + // ensures it's not found by normal content + var contentFound = await ContentEditingService.GetAsync(result.Result.Content!.Key); + Assert.IsNull(contentFound); + } + + [Test] + public async Task Can_Create_With_Explicit_Key() + { + var contentType = CreateInvariantContentType(); + + var key = Guid.NewGuid(); + var createModel = new ContentBlueprintCreateModel + { + Key = key, + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var result = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + Assert.IsNotNull(result.Result.Content); + }); + Assert.Multiple(() => + { + Assert.IsTrue(result.Result.Content.HasIdentity); + Assert.AreEqual(key, result.Result.Content.Key); + Assert.AreEqual("The title value", result.Result.Content.GetValue("title")); + }); + + // re-get and verify creation + var blueprint = await ContentBlueprintEditingService.GetAsync(key); + Assert.IsNotNull(blueprint); + Assert.AreEqual(result.Result.Content.Id, blueprint.Id); + } + + [Test] + public async Task Cannot_Create_With_Duplicate_Name_For_The_Same_Content_Type() + { + var contentType = CreateInvariantContentType(); + + var createModel = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var result1 = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result1.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result1.Status); + Assert.IsNotNull(result1.Result); + }); + + // create another blueprint with the same name + var result2 = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsFalse(result2.Success); + Assert.AreEqual(ContentEditingOperationStatus.DuplicateName, result2.Status); + Assert.IsNotNull(result2.Result); + }); + Assert.IsNull(result2.Result.Content); + } + + [Test] + public async Task Can_Create_With_Different_Name() + { + var contentType = CreateInvariantContentType(); + + var createModel1 = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint 1", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var result1 = await ContentBlueprintEditingService.CreateAsync(createModel1, Constants.Security.SuperUserKey); + Assert.Multiple(() => + { + Assert.IsTrue(result1.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result1.Status); + Assert.IsNotNull(result1.Result); + }); + + var createModel2 = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint 2", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + // create another blueprint + var result2 = await ContentBlueprintEditingService.CreateAsync(createModel2, Constants.Security.SuperUserKey); + Assert.Multiple(() => + { + Assert.IsTrue(result2.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result2.Status); + Assert.IsNotNull(result2.Result); + }); + } + + [Test] + public async Task Can_Create_With_Duplicate_Name_For_Different_Content_Types() + { + var contentType1 = ContentTypeBuilder.CreateContentMetaContentType(); + contentType1.AllowedTemplates = null; + contentType1.AllowedAsRoot = true; + ContentTypeService.Save(contentType1); + + var createModel1 = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType1.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var result1 = await ContentBlueprintEditingService.CreateAsync(createModel1, Constants.Security.SuperUserKey); + Assert.Multiple(() => + { + Assert.IsTrue(result1.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result1.Status); + Assert.IsNotNull(result1.Result); + }); + + var contentType2 = CreateInvariantContentType(); + + var createModel2 = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType2.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + // create another blueprint + var result2 = await ContentBlueprintEditingService.CreateAsync(createModel2, Constants.Security.SuperUserKey); + Assert.Multiple(() => + { + Assert.IsTrue(result2.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result2.Status); + Assert.IsNotNull(result2.Result); + }); + } + + [Test] + public async Task Cannot_Create_When_Content_Type_Not_Found() + { + var createModel1 = new ContentBlueprintCreateModel + { + ContentTypeKey = Guid.NewGuid(), + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create Blueprint", + }; + + var result = await ContentBlueprintEditingService.CreateAsync(createModel1, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.ContentTypeNotFound, result.Status); + Assert.IsNotNull(result.Result); + }); + Assert.IsNull(result.Result.Content); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.CreateFromContent.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.CreateFromContent.cs new file mode 100644 index 0000000000..c7af2fc560 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.CreateFromContent.cs @@ -0,0 +1,140 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Services.OperationStatus; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +public partial class ContentBlueprintEditingServiceTests +{ + [Test] + public async Task Can_Create_From_Content() + { + var contentType = CreateInvariantContentType(); + + var createModel = new ContentCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Create", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var createContentResult = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(createContentResult.Success); + Assert.IsNotNull(createContentResult.Result); + }); + + const string name = "Test Create From Content Blueprint"; + + var result = await ContentBlueprintEditingService.CreateFromContentAsync( + createContentResult.Result.Content!.Key, + name, + null, + Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + }); + VerifyCreate(result.Result.Content); + + // re-get and re-test + VerifyCreate(await ContentBlueprintEditingService.GetAsync(result.Result.Content!.Key)); + + void VerifyCreate(IContent? createdBlueprint) + { + Assert.IsNotNull(createdBlueprint); + Assert.Multiple(() => + { + Assert.AreNotEqual(Guid.Empty, createdBlueprint.Key); + Assert.IsTrue(createdBlueprint.HasIdentity); + Assert.AreEqual(name, createdBlueprint.Name); + Assert.AreEqual("The title value", createdBlueprint.GetValue("title")); + }); + } + + // ensures it's not found by normal content + var contentFound = await ContentEditingService.GetAsync(result.Result.Content!.Key); + Assert.IsNull(contentFound); + } + + [TestCase(true)] + [TestCase(false)] + public async Task Can_Create_From_Content_With_Explicit_Key(bool variant) + { + var content = await (variant ? CreateVariantContent() : CreateInvariantContent()); + + var key = Guid.NewGuid(); + const string name = "Test Create From Content Blueprint"; + + var result = await ContentBlueprintEditingService.CreateFromContentAsync( + content.Key, + name, + key, + Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + Assert.IsNotNull(result.Result.Content); + }); + Assert.Multiple(() => + { + Assert.IsTrue(result.Result.Content.HasIdentity); + Assert.AreEqual(key, result.Result.Content.Key); + Assert.AreEqual(name, result.Result.Content.Name); + }); + + // re-get and verify creation + var blueprint = await ContentBlueprintEditingService.GetAsync(key); + Assert.IsNotNull(blueprint); + Assert.AreEqual(result.Result.Content.Id, blueprint.Id); + } + + [TestCase(true)] + [TestCase(false)] + public async Task Cannot_Create_From_Content_With_Duplicate_Name(bool variant) + { + var content = await (variant ? CreateVariantContent() : CreateInvariantContent()); + + const string name = "Test Create From Content Blueprint"; + + var result1 = await ContentBlueprintEditingService.CreateFromContentAsync( + content.Key, + name, + null, + Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result1.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result1.Status); + Assert.IsNotNull(result1.Result); + }); + + // create another blueprint with the same name + var result2 = await ContentBlueprintEditingService.CreateFromContentAsync( + content.Key, + name, + null, + Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsFalse(result2.Success); + Assert.AreEqual(ContentEditingOperationStatus.DuplicateName, result2.Status); + Assert.IsNotNull(result2.Result); + }); + Assert.IsNull(result2.Result.Content); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Delete.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Delete.cs new file mode 100644 index 0000000000..1091cfc8db --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Delete.cs @@ -0,0 +1,39 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Services.OperationStatus; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +public partial class ContentBlueprintEditingServiceTests +{ + [TestCase(true)] + [TestCase(false)] + public async Task Can_Delete(bool variant) + { + var blueprint = await (variant ? CreateVariantContentBlueprint() : CreateInvariantContentBlueprint()); + + var result = await ContentBlueprintEditingService.DeleteAsync(blueprint.Key, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + }); + + // re-get and verify deletion + blueprint = await ContentBlueprintEditingService.GetAsync(blueprint.Key); + Assert.IsNull(blueprint); + } + + [Test] + public async Task Cannot_Delete_Non_Existing() + { + var result = await ContentBlueprintEditingService.DeleteAsync(Guid.NewGuid(), Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.NotFound, result.Status); + }); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Get.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Get.cs new file mode 100644 index 0000000000..4852136d30 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Get.cs @@ -0,0 +1,24 @@ +using NUnit.Framework; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +public partial class ContentBlueprintEditingServiceTests +{ + [TestCase(true)] + [TestCase(true)] + public async Task Can_Get(bool variant) + { + var blueprint = await (variant ? CreateVariantContentBlueprint() : CreateInvariantContentBlueprint()); + + var result = await ContentBlueprintEditingService.GetAsync(blueprint.Key); + Assert.IsNotNull(result); + Assert.AreEqual(blueprint.Key, result.Key); + } + + [Test] + public async Task Cannot_Get_Non_Existing() + { + var result = await ContentBlueprintEditingService.GetAsync(Guid.NewGuid()); + Assert.IsNull(result); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Update.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Update.cs new file mode 100644 index 0000000000..5f340e8e6a --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.Update.cs @@ -0,0 +1,152 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Services.OperationStatus; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +public partial class ContentBlueprintEditingServiceTests +{ + [Test] + public async Task Can_Update_Invariant() + { + var blueprint = await CreateInvariantContentBlueprint(); + + var updateModel = new ContentBlueprintUpdateModel + { + InvariantName = "Updated Blueprint Name", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The updated title" }, + new PropertyValueModel { Alias = "text", Value = "The updated text" }, + }, + }; + + var result = await ContentBlueprintEditingService.UpdateAsync(blueprint.Key, updateModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + }); + VerifyUpdate(result.Result.Content); + + // re-get and re-test + VerifyUpdate(await ContentBlueprintEditingService.GetAsync(blueprint.Key)); + + void VerifyUpdate(IContent? updatedContent) + { + Assert.IsNotNull(updatedContent); + Assert.Multiple(() => + { + Assert.AreEqual("Updated Blueprint Name", updatedContent.Name); + Assert.AreEqual("The updated title", updatedContent.GetValue("title")); + Assert.AreEqual("The updated text", updatedContent.GetValue("text")); + }); + } + } + + [Test] + public async Task Can_Update_Variant() + { + var blueprint = await CreateVariantContentBlueprint(); + + var updateModel = new ContentBlueprintUpdateModel + { + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "invariantTitle", Value = "The updated blueprint invariant title" }, + }, + Variants = new[] + { + new VariantModel + { + Culture = "en-US", + Name = "Updated Blueprint English Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The updated English title" }, + }, + }, + new VariantModel + { + Culture = "da-DK", + Name = "Updated Blueprint Danish Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The updated Danish title" }, + }, + }, + }, + }; + + var result = await ContentBlueprintEditingService.UpdateAsync(blueprint.Key, updateModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, result.Status); + }); + VerifyUpdate(result.Result.Content); + + // re-get and re-test + VerifyUpdate(await ContentBlueprintEditingService.GetAsync(blueprint.Key)); + + void VerifyUpdate(IContent? updatedContent) + { + Assert.IsNotNull(updatedContent); + Assert.Multiple(() => + { + Assert.AreEqual("Updated Blueprint English Name", updatedContent.GetCultureName("en-US")); + Assert.AreEqual("Updated Blueprint Danish Name", updatedContent.GetCultureName("da-DK")); + Assert.AreEqual("The updated blueprint invariant title", updatedContent.GetValue("invariantTitle")); + Assert.AreEqual("The updated English title", updatedContent.GetValue("variantTitle", "en-US")); + Assert.AreEqual("The updated Danish title", updatedContent.GetValue("variantTitle", "da-DK")); + }); + } + } + + [Test] + public async Task Cannot_Update_With_Duplicate_Name_For_The_Same_Content_Type() + { + var blueprintToUpdate = await CreateInvariantContentBlueprint(); + + // create another blueprint of the same content type + var createModel = new ContentBlueprintCreateModel + { + ContentTypeKey = blueprintToUpdate.ContentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Test Blueprint", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The title value" }, + }, + }; + + var createResult = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsTrue(createResult.Success); + Assert.AreEqual(ContentEditingOperationStatus.Success, createResult.Status); + Assert.IsNotNull(createResult.Result); + }); + + // update a blueprint with the same name + var updateModel = new ContentBlueprintUpdateModel + { + InvariantName = "Test Blueprint", + }; + + var updateResult = await ContentBlueprintEditingService.UpdateAsync(blueprintToUpdate.Key, updateModel, Constants.Security.SuperUserKey); + + Assert.Multiple(() => + { + Assert.IsFalse(updateResult.Success); + Assert.AreEqual(ContentEditingOperationStatus.DuplicateName, updateResult.Status); + Assert.IsNotNull(updateResult.Result); + }); + Assert.IsNull(updateResult.Result.Content); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.cs new file mode 100644 index 0000000000..088799e271 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentBlueprintEditingServiceTests.cs @@ -0,0 +1,74 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +/// +/// Tests for the content blueprint editing service. Please notice that a lot of the functional tests are covered by the content +/// editing service tests, since these services share the same base implementation. +/// +public partial class ContentBlueprintEditingServiceTests : ContentEditingServiceTestsBase +{ + private async Task CreateInvariantContentBlueprint() + { + var contentType = CreateInvariantContentType(); + + var createModel = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Initial Blueprint Name", + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The initial title" }, + new PropertyValueModel { Alias = "text", Value = "The initial text" }, + }, + }; + + var result = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsTrue(result.Success); + return result.Result.Content!; + } + + private async Task CreateVariantContentBlueprint() + { + var contentType = await CreateVariantContentType(); + + var createModel = new ContentBlueprintCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "invariantTitle", Value = "The initial invariant title" }, + }, + Variants = new[] + { + new VariantModel + { + Culture = "en-US", + Name = "Initial Blueprint English Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The initial English title" }, + }, + }, + new VariantModel + { + Culture = "da-DK", + Name = "Initial Blueprint Danish Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The initial Danish title" }, + }, + }, + }, + }; + + var result = await ContentBlueprintEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsTrue(result.Success); + return result.Result.Content!; + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.MoveToRecyleBin.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.MoveToRecycleBin.cs similarity index 100% rename from tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.MoveToRecyleBin.cs rename to tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.MoveToRecycleBin.cs diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.cs index 115d95fa05..d3c07050cb 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTests.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; -using NUnit.Framework; +using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Models; @@ -8,168 +7,22 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; -using Umbraco.Cms.Infrastructure.Serialization; using Umbraco.Cms.Tests.Common.Builders; -using Umbraco.Cms.Tests.Common.Builders.Extensions; -using Umbraco.Cms.Tests.Common.Testing; -using Umbraco.Cms.Tests.Integration.Testing; namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; -[TestFixture] -[UmbracoTest( - Database = UmbracoTestOptions.Database.NewSchemaPerTest, - PublishedRepositoryEvents = true, - WithApplication = true)] -public partial class ContentEditingServiceTests : UmbracoIntegrationTestWithContent +public partial class ContentEditingServiceTests : ContentEditingServiceTestsBase { [SetUp] public void Setup() => ContentRepositoryBase.ThrowOnWarning = true; protected override void CustomTestSetup(IUmbracoBuilder builder) - { - builder.AddNotificationHandler(); - // FIXME: These test NEED the System.Text.Json serializer. - // When the ContextualJsonSerializer is removed, this can be removed too. - builder.Services.AddSingleton(); - } + => builder.AddNotificationHandler(); private ITemplateService TemplateService => GetRequiredService(); - private ILanguageService LanguageService => GetRequiredService(); - - private IContentEditingService ContentEditingService => GetRequiredService(); - private IJsonSerializer JsonSerializer => GetRequiredService(); - private IContentType CreateInvariantContentType(params ITemplate[] templates) - { - var contentTypeBuilder = new ContentTypeBuilder() - .WithAlias("invariantTest") - .WithName("Invariant Test") - .WithContentVariation(ContentVariation.Nothing) - .AddPropertyType() - .WithAlias("title") - .WithName("Title") - .WithVariations(ContentVariation.Nothing) - .Done() - .AddPropertyType() - .WithAlias("text") - .WithName("Text") - .WithVariations(ContentVariation.Nothing) - .Done(); - - foreach (var template in templates) - { - contentTypeBuilder - .AddAllowedTemplate() - .WithId(template.Id) - .WithAlias(template.Alias) - .WithName(template.Name ?? template.Alias) - .Done(); - } - - if (templates.Any()) - { - contentTypeBuilder.WithDefaultTemplateId(templates.First().Id); - } - - var contentType = contentTypeBuilder.Build(); - contentType.AllowedAsRoot = true; - ContentTypeService.Save(contentType); - - return contentType; - } - - private async Task CreateVariantContentType() - { - var language = new LanguageBuilder() - .WithCultureInfo("da-DK") - .Build(); - await LanguageService.CreateAsync(language, Constants.Security.SuperUserKey); - - var contentType = new ContentTypeBuilder() - .WithAlias("cultureVariationTest") - .WithName("Culture Variation Test") - .WithContentVariation(ContentVariation.Culture) - .AddPropertyType() - .WithAlias("variantTitle") - .WithName("Variant Title") - .WithVariations(ContentVariation.Culture) - .Done() - .AddPropertyType() - .WithAlias("invariantTitle") - .WithName("Invariant Title") - .WithVariations(ContentVariation.Nothing) - .Done() - .Build(); - contentType.AllowedAsRoot = true; - ContentTypeService.Save(contentType); - return contentType; - } - - private async Task CreateInvariantContent(params ITemplate[] templates) - { - var contentType = CreateInvariantContentType(templates); - - var createModel = new ContentCreateModel - { - ContentTypeKey = contentType.Key, - ParentKey = Constants.System.RootKey, - InvariantName = "Initial Name", - TemplateKey = templates.FirstOrDefault()?.Key, - InvariantProperties = new[] - { - new PropertyValueModel { Alias = "title", Value = "The initial title" }, - new PropertyValueModel { Alias = "text", Value = "The initial text" } - } - }; - - var result = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); - Assert.IsTrue(result.Success); - return result.Result.Content!; - } - - private async Task CreateVariantContent() - { - var contentType = await CreateVariantContentType(); - - var createModel = new ContentCreateModel - { - ContentTypeKey = contentType.Key, - ParentKey = Constants.System.RootKey, - InvariantProperties = new[] - { - new PropertyValueModel { Alias = "invariantTitle", Value = "The initial invariant title" } - }, - Variants = new [] - { - new VariantModel - { - Culture = "en-US", - Name = "Initial English Name", - Properties = new [] - { - new PropertyValueModel { Alias = "variantTitle", Value = "The initial English title" } - } - }, - new VariantModel - { - Culture = "da-DK", - Name = "Initial Danish Name", - Properties = new [] - { - new PropertyValueModel { Alias = "variantTitle", Value = "The initial Danish title" } - } - } - } - }; - - var result = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); - Assert.IsTrue(result.Success); - return result.Result.Content!; - } - private async Task CreateTextPageContentTypeAsync() { var template = TemplateBuilder.CreateTextPageTemplate(); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTestsBase.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTestsBase.cs new file mode 100644 index 0000000000..a8c9eca84a --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentEditingServiceTestsBase.cs @@ -0,0 +1,153 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.ContentEditing; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Tests.Common.Builders; +using Umbraco.Cms.Tests.Common.Builders.Extensions; +using Umbraco.Cms.Tests.Common.Testing; +using Umbraco.Cms.Tests.Integration.Testing; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; + +[TestFixture] +[UmbracoTest( + Database = UmbracoTestOptions.Database.NewSchemaPerTest, + PublishedRepositoryEvents = true, + WithApplication = true)] +public abstract class ContentEditingServiceTestsBase : UmbracoIntegrationTestWithContent +{ + protected IContentEditingService ContentEditingService => GetRequiredService(); + + protected IContentBlueprintEditingService ContentBlueprintEditingService => GetRequiredService(); + + private ILanguageService LanguageService => GetRequiredService(); + + protected IContentType CreateInvariantContentType(params ITemplate[] templates) + { + var contentTypeBuilder = new ContentTypeBuilder() + .WithAlias("invariantTest") + .WithName("Invariant Test") + .WithContentVariation(ContentVariation.Nothing) + .AddPropertyType() + .WithAlias("title") + .WithName("Title") + .WithVariations(ContentVariation.Nothing) + .Done() + .AddPropertyType() + .WithAlias("text") + .WithName("Text") + .WithVariations(ContentVariation.Nothing) + .Done(); + + foreach (var template in templates) + { + contentTypeBuilder + .AddAllowedTemplate() + .WithId(template.Id) + .WithAlias(template.Alias) + .WithName(template.Name ?? template.Alias) + .Done(); + } + + if (templates.Any()) + { + contentTypeBuilder.WithDefaultTemplateId(templates.First().Id); + } + + var contentType = contentTypeBuilder.Build(); + contentType.AllowedAsRoot = true; + ContentTypeService.Save(contentType); + + return contentType; + } + + protected async Task CreateVariantContentType() + { + var language = new LanguageBuilder() + .WithCultureInfo("da-DK") + .Build(); + await LanguageService.CreateAsync(language, Constants.Security.SuperUserKey); + + var contentType = new ContentTypeBuilder() + .WithAlias("cultureVariationTest") + .WithName("Culture Variation Test") + .WithContentVariation(ContentVariation.Culture) + .AddPropertyType() + .WithAlias("variantTitle") + .WithName("Variant Title") + .WithVariations(ContentVariation.Culture) + .Done() + .AddPropertyType() + .WithAlias("invariantTitle") + .WithName("Invariant Title") + .WithVariations(ContentVariation.Nothing) + .Done() + .Build(); + contentType.AllowedAsRoot = true; + ContentTypeService.Save(contentType); + return contentType; + } + + protected async Task CreateInvariantContent(params ITemplate[] templates) + { + var contentType = CreateInvariantContentType(templates); + + var createModel = new ContentCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantName = "Initial Name", + TemplateKey = templates.FirstOrDefault()?.Key, + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "title", Value = "The initial title" }, + new PropertyValueModel { Alias = "text", Value = "The initial text" }, + }, + }; + + var result = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsTrue(result.Success); + return result.Result.Content!; + } + + protected async Task CreateVariantContent() + { + var contentType = await CreateVariantContentType(); + + var createModel = new ContentCreateModel + { + ContentTypeKey = contentType.Key, + ParentKey = Constants.System.RootKey, + InvariantProperties = new[] + { + new PropertyValueModel { Alias = "invariantTitle", Value = "The initial invariant title" }, + }, + Variants = new[] + { + new VariantModel + { + Culture = "en-US", + Name = "Initial English Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The initial English title" }, + }, + }, + new VariantModel + { + Culture = "da-DK", + Name = "Initial Danish Name", + Properties = new[] + { + new PropertyValueModel { Alias = "variantTitle", Value = "The initial Danish title" }, + }, + }, + }, + }; + + var result = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsTrue(result.Success); + return result.Result.Content!; + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Scheduling.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Scheduling.cs index fbee258d45..5fad7f9d17 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Scheduling.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/ContentPublishingServiceTests.Scheduling.cs @@ -1,9 +1,7 @@ using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.ContentPublishing; using Umbraco.Cms.Core.Services.OperationStatus; -using Umbraco.Cms.Tests.Common.Builders; namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services; diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj index f9bb577d76..98882ea615 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj +++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj @@ -52,10 +52,13 @@ + + ContentEditingServiceTests.cs + ContentEditingServiceTests.cs - + ContentEditingServiceTests.cs @@ -70,15 +73,18 @@ ContentEditingServiceTests.cs - - ContentEditingServiceTests.cs - ContentEditingServiceTests.cs + + ContentEditingServiceTests.cs + ContentPublishingServiceTests.cs + + ContentPublishingServiceTests.cs + ContentPublishingServiceTests.cs @@ -121,8 +127,20 @@ MediaTypeEditingServiceTests.cs - - ContentEditingServiceTests.cs + + ContentBlueprintEditingServiceTests.cs + + + ContentBlueprintEditingServiceTests.cs + + + ContentBlueprintEditingServiceTests.cs + + + ContentBlueprintEditingServiceTests.cs + + + ContentBlueprintEditingServiceTests.cs