diff --git a/src/Umbraco.Core/Models/ContentPropertySettings.cs b/src/Umbraco.Core/Models/ContentPropertySettings.cs index 46b130bc9e..7953a5a1d5 100644 --- a/src/Umbraco.Core/Models/ContentPropertySettings.cs +++ b/src/Umbraco.Core/Models/ContentPropertySettings.cs @@ -10,4 +10,6 @@ public class ContentPropertySettings public ISet ReservedFieldNames => _reservedFieldNames; public bool AddReservedFieldName(string name) => _reservedFieldNames.Add(name); + + public void AddReservedFieldNames(ISet names) => _reservedFieldNames.UnionWith(names); } diff --git a/src/Umbraco.Core/Models/MediaPropertySettings.cs b/src/Umbraco.Core/Models/MediaPropertySettings.cs index db3eafa218..e13512aa26 100644 --- a/src/Umbraco.Core/Models/MediaPropertySettings.cs +++ b/src/Umbraco.Core/Models/MediaPropertySettings.cs @@ -10,4 +10,6 @@ public class MediaPropertySettings public ISet ReservedFieldNames => _reservedFieldNames; public bool AddReservedFieldName(string name) => _reservedFieldNames.Add(name); + + public void AddReservedFieldNames(ISet names) => _reservedFieldNames.UnionWith(names); } diff --git a/src/Umbraco.Core/Models/MemberPropertySettings.cs b/src/Umbraco.Core/Models/MemberPropertySettings.cs index b7e8b754c8..b5271fb75c 100644 --- a/src/Umbraco.Core/Models/MemberPropertySettings.cs +++ b/src/Umbraco.Core/Models/MemberPropertySettings.cs @@ -10,4 +10,6 @@ public class MemberPropertySettings public ISet ReservedFieldNames => _reservedFieldNames; public bool AddReservedFieldName(string name) => _reservedFieldNames.Add(name); + + public void AddReservedFieldNames(ISet names) => _reservedFieldNames.UnionWith(names); } diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedMember.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedMember.cs index 9095a4aaa3..0d028961f6 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedMember.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedMember.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Cms.Core.Models.PublishedContent; +namespace Umbraco.Cms.Core.Models.PublishedContent; public interface IPublishedMember : IPublishedContent { diff --git a/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingService.cs b/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingService.cs index e44b66b971..a63d566c35 100644 --- a/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingService.cs +++ b/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingService.cs @@ -3,7 +3,6 @@ using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentEditing; using Umbraco.Cms.Core.Models.ContentTypeEditing; -using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Services.OperationStatus; using Umbraco.Cms.Core.Strings; using Umbraco.Extensions; @@ -16,6 +15,7 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase< { private readonly ITemplateService _templateService; private readonly IElementSwitchValidator _elementSwitchValidator; + private readonly IReservedFieldNamesService _reservedFieldNamesService; private readonly IContentTypeService _contentTypeService; public ContentTypeEditingService( @@ -24,12 +24,33 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase< IDataTypeService dataTypeService, IEntityService entityService, IShortStringHelper shortStringHelper, - IElementSwitchValidator elementSwitchValidator) + IElementSwitchValidator elementSwitchValidator, + IReservedFieldNamesService reservedFieldNamesService) : base(contentTypeService, contentTypeService, dataTypeService, entityService, shortStringHelper) { _contentTypeService = contentTypeService; _templateService = templateService; _elementSwitchValidator = elementSwitchValidator; + _reservedFieldNamesService = reservedFieldNamesService; + } + + [Obsolete("Use the constructor that is not marked obsolete, will be removed in v17")] + public ContentTypeEditingService( + IContentTypeService contentTypeService, + ITemplateService templateService, + IDataTypeService dataTypeService, + IEntityService entityService, + IShortStringHelper shortStringHelper, + IElementSwitchValidator elementSwitchValidator) + : this( + contentTypeService, + templateService, + dataTypeService, + entityService, + shortStringHelper, + elementSwitchValidator, + StaticServiceProvider.Instance.GetRequiredService()) + { } [Obsolete("Use the constructor that is not marked obsolete, will be removed in v16")] @@ -39,11 +60,15 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase< IDataTypeService dataTypeService, IEntityService entityService, IShortStringHelper shortStringHelper) - : base(contentTypeService, contentTypeService, dataTypeService, entityService, shortStringHelper) + : this( + contentTypeService, + templateService, + dataTypeService, + entityService, + shortStringHelper, + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService()) { - _contentTypeService = contentTypeService; - _templateService = templateService; - _elementSwitchValidator = StaticServiceProvider.Instance.GetRequiredService(); } public async Task> CreateAsync(ContentTypeCreateModel model, Guid userKey) @@ -184,4 +209,6 @@ internal sealed class ContentTypeEditingService : ContentTypeEditingServiceBase< protected override UmbracoObjectTypes ContentTypeObjectType => UmbracoObjectTypes.DocumentType; protected override UmbracoObjectTypes ContainerObjectType => UmbracoObjectTypes.DocumentTypeContainer; + + protected override ISet GetReservedFieldNames() => _reservedFieldNamesService.GetDocumentReservedFieldNames(); } diff --git a/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs b/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs index 500d590284..a86d9186e0 100644 --- a/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs +++ b/src/Umbraco.Core/Services/ContentTypeEditing/ContentTypeEditingServiceBase.cs @@ -1,6 +1,5 @@ using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentTypeEditing; -using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Services.OperationStatus; using Umbraco.Cms.Core.Strings; using Umbraco.Extensions; @@ -18,7 +17,6 @@ internal abstract class ContentTypeEditingServiceBase GetReservedFieldNames(); + private bool ContainsReservedPropertyTypeAlias(ContentTypeEditingModelBase model) { // Because of models builder you cannot have an alias that already exists in IPublishedContent, for instance Path. // Since MyModel.Path would conflict with IPublishedContent.Path. - var reservedPropertyTypeNames = typeof(IPublishedContent).GetPublicProperties().Select(x => x.Name) - .Union(typeof(IPublishedContent).GetPublicMethods().Select(x => x.Name)) - .ToArray(); + ISet reservedPropertyTypeNames = GetReservedFieldNames(); return model.Properties.Any(propertyType => reservedPropertyTypeNames.InvariantContains(propertyType.Alias)); } diff --git a/src/Umbraco.Core/Services/ContentTypeEditing/MediaTypeEditingService.cs b/src/Umbraco.Core/Services/ContentTypeEditing/MediaTypeEditingService.cs index 11def4a333..069f72cb12 100644 --- a/src/Umbraco.Core/Services/ContentTypeEditing/MediaTypeEditingService.cs +++ b/src/Umbraco.Core/Services/ContentTypeEditing/MediaTypeEditingService.cs @@ -1,4 +1,6 @@ -using Umbraco.Cms.Core.Media; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Media; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentTypeEditing; using Umbraco.Cms.Core.PropertyEditors; @@ -13,7 +15,25 @@ internal sealed class MediaTypeEditingService : ContentTypeEditingServiceBase(); } public async Task> CreateAsync(MediaTypeCreateModel model, Guid userKey) @@ -145,6 +166,8 @@ internal sealed class MediaTypeEditingService : ContentTypeEditingServiceBase UmbracoObjectTypes.MediaTypeContainer; + protected override ISet GetReservedFieldNames() => _reservedFieldNamesService.GetMediaReservedFieldNames(); + private async Task>> FetchAllowedFileExtensionsByMediaTypeAsync(IEnumerable mediaTypes) { var allowedFileExtensionsByMediaType = new Dictionary>(); diff --git a/src/Umbraco.Core/Services/ContentTypeEditing/MemberTypeEditingService.cs b/src/Umbraco.Core/Services/ContentTypeEditing/MemberTypeEditingService.cs index 60707728af..dd566b6a2b 100644 --- a/src/Umbraco.Core/Services/ContentTypeEditing/MemberTypeEditingService.cs +++ b/src/Umbraco.Core/Services/ContentTypeEditing/MemberTypeEditingService.cs @@ -1,4 +1,6 @@ -using Umbraco.Cms.Core.Models; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentTypeEditing; using Umbraco.Cms.Core.Models.Membership; using Umbraco.Cms.Core.Services.OperationStatus; @@ -10,7 +12,24 @@ internal sealed class MemberTypeEditingService : ContentTypeEditingServiceBase(); } public async Task> CreateAsync(MemberTypeCreateModel model, Guid userKey) @@ -79,6 +99,8 @@ internal sealed class MemberTypeEditingService : ContentTypeEditingServiceBase throw new NotSupportedException("Member type tree does not support containers"); + protected override ISet GetReservedFieldNames() => _reservedFieldNamesService.GetMemberReservedFieldNames(); + private void UpdatePropertyTypeVisibility(IMemberType memberType, MemberTypeModelBase model) { foreach (MemberTypePropertyTypeModel propertyType in model.Properties) diff --git a/src/Umbraco.Infrastructure/ModelsBuilder/Options/ConfigurePropertySettingsOptions.cs b/src/Umbraco.Infrastructure/ModelsBuilder/Options/ConfigurePropertySettingsOptions.cs new file mode 100644 index 0000000000..fe7cfb45cf --- /dev/null +++ b/src/Umbraco.Infrastructure/ModelsBuilder/Options/ConfigurePropertySettingsOptions.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Infrastructure.ModelsBuilder.Options; + +public class ConfigurePropertySettingsOptions : + IConfigureOptions, + IConfigureOptions, + IConfigureOptions +{ + + public void Configure(ContentPropertySettings options) + { + var reservedProperties = typeof(IPublishedContent).GetPublicProperties().Select(x => x.Name).ToHashSet(); + var reservedMethods = typeof(IPublishedContent).GetPublicMethods().Select(x => x.Name).ToHashSet(); + options.AddReservedFieldNames(reservedProperties); + options.AddReservedFieldNames(reservedMethods); + } + + public void Configure(MemberPropertySettings options) + { + var reservedProperties = typeof(IPublishedMember).GetPublicProperties().Select(x => x.Name).ToHashSet(); + var reservedMethods = typeof(IPublishedMember).GetPublicMethods().Select(x => x.Name).ToHashSet(); + options.AddReservedFieldNames(reservedProperties); + options.AddReservedFieldNames(reservedMethods); + } + + public void Configure(MediaPropertySettings options) + { + var reservedProperties = typeof(IPublishedContent).GetPublicProperties().Select(x => x.Name).ToHashSet(); + var reservedMethods = typeof(IPublishedContent).GetPublicMethods().Select(x => x.Name).ToHashSet(); + options.AddReservedFieldNames(reservedProperties); + options.AddReservedFieldNames(reservedMethods); + } +} diff --git a/src/Umbraco.Infrastructure/PublishedCache/ReservedFieldNamesService.cs b/src/Umbraco.Infrastructure/PublishedCache/ReservedFieldNamesService.cs index 8cbdf4f130..c4d981ef10 100644 --- a/src/Umbraco.Infrastructure/PublishedCache/ReservedFieldNamesService.cs +++ b/src/Umbraco.Infrastructure/PublishedCache/ReservedFieldNamesService.cs @@ -1,8 +1,6 @@ using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Services; -using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.PublishedCache; @@ -22,33 +20,9 @@ internal class ReservedFieldNamesService : IReservedFieldNamesService _mediaPropertySettings = mediaPropertySettings.Value; } - public ISet GetDocumentReservedFieldNames() - { - var reservedProperties = typeof(IPublishedContent).GetPublicProperties().Select(x => x.Name).ToHashSet(); - var reservedMethods = typeof(IPublishedContent).GetPublicMethods().Select(x => x.Name).ToHashSet(); - reservedProperties.UnionWith(reservedMethods); - reservedProperties.UnionWith(_contentPropertySettings.ReservedFieldNames); + public ISet GetDocumentReservedFieldNames() => _contentPropertySettings.ReservedFieldNames; - return reservedProperties; - } + public ISet GetMediaReservedFieldNames() => _mediaPropertySettings.ReservedFieldNames; - public ISet GetMediaReservedFieldNames() - { - var reservedProperties = typeof(IPublishedContent).GetPublicProperties().Select(x => x.Name).ToHashSet(); - var reservedMethods = typeof(IPublishedContent).GetPublicMethods().Select(x => x.Name).ToHashSet(); - reservedProperties.UnionWith(reservedMethods); - reservedProperties.UnionWith(_mediaPropertySettings.ReservedFieldNames); - - return reservedProperties; - } - - public ISet GetMemberReservedFieldNames() - { - var reservedProperties = typeof(IPublishedMember).GetPublicProperties().Select(x => x.Name).ToHashSet(); - var reservedMethods = typeof(IPublishedMember).GetPublicMethods().Select(x => x.Name).ToHashSet(); - reservedProperties.UnionWith(reservedMethods); - reservedProperties.UnionWith(_memberPropertySettings.ReservedFieldNames); - - return reservedProperties; - } + public ISet GetMemberReservedFieldNames() => _memberPropertySettings.ReservedFieldNames; } diff --git a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs index 3784781413..045a5107bb 100644 --- a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs +++ b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs @@ -15,6 +15,7 @@ using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Infrastructure.ModelsBuilder; using Umbraco.Cms.Infrastructure.ModelsBuilder.Building; +using Umbraco.Cms.Infrastructure.ModelsBuilder.Options; using Umbraco.Cms.Web.Common.ModelsBuilder; using Umbraco.Cms.Web.Common.ModelsBuilder.InMemoryAuto; @@ -141,6 +142,8 @@ public static class UmbracoBuilderDependencyInjectionExtensions builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.ConfigureOptions(); + return builder; } diff --git a/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs b/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs index f99e6dfbf5..9b59c01657 100644 --- a/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs @@ -21,6 +21,7 @@ using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; using Umbraco.Cms.Infrastructure.Examine; using Umbraco.Cms.Infrastructure.HostedServices; +using Umbraco.Cms.Infrastructure.PublishedCache; using Umbraco.Cms.Persistence.EFCore.Locking; using Umbraco.Cms.Persistence.EFCore.Scoping; using Umbraco.Cms.Tests.Common.TestHelpers.Stubs; @@ -95,6 +96,8 @@ public static class UmbracoBuilderExtensions builder.Services.AddSingleton>(); builder.Services.AddSingleton>(); + builder.Services.AddSingleton(); + return builder; } diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderDisabledTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderDisabledTests.cs new file mode 100644 index 0000000000..fa9dbbeddb --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderDisabledTests.cs @@ -0,0 +1,35 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Services.OperationStatus; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services; + +public class + ContentTypeEditingServiceModelsBuilderDisabledTests : ContentTypeEditingServiceModelsBuilderDisabledTestsBase +{ + // test some properties from IPublishedContent + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Id) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Name) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.SortOrder) })] + // test some properties from IPublishedElement + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Properties) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.ContentType) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Key) })] + // test some methods from IPublishedContent + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.IsDraft) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.IsPublished) })] + public async Task Can_Use_Invalid_ModelsBuilder_PropertyType_Alias_When_ModelsBuilderIsDisabled( + string propertyTypeAlias) + { + var propertyType = ContentTypePropertyTypeModel("Test Property", propertyTypeAlias); + var createModel = ContentTypeCreateModel("Test", propertyTypes: new[] { propertyType }); + + var result = await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.Multiple(() => + { + Assert.IsTrue(result.Success); + Assert.AreEqual(ContentTypeOperationStatus.Success, result.Status); + }); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderDisabledTestsBase.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderDisabledTestsBase.cs new file mode 100644 index 0000000000..55e632ba8a --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderDisabledTestsBase.cs @@ -0,0 +1,11 @@ +using Umbraco.Cms.Infrastructure.ModelsBuilder.Options; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services; + +/// +/// Unlike this testbase does not configure the modelsbuilder based +/// which has the same effect as disabling it completely as only loads in that part anyway. +/// +public class ContentTypeEditingServiceModelsBuilderDisabledTestsBase : ContentTypeEditingServiceTestsBase +{ +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderEnabledTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderEnabledTests.cs new file mode 100644 index 0000000000..88be628734 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderEnabledTests.cs @@ -0,0 +1,34 @@ +using NUnit.Framework; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Services.OperationStatus; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services; + +public class ContentTypeEditingServiceModelsBuilderEnabledTests : ContentTypeEditingServiceModelsBuilderEnabledTestsBase +{ + // test some properties from IPublishedContent + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Id) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Name) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.SortOrder) })] + // test some properties from IPublishedElement + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Properties) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.ContentType) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.Key) })] + // test some methods from IPublishedContent + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.IsDraft) })] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { nameof(IPublishedContent.IsPublished) })] + public async Task Cannot_Use_Invalid_ModelsBuilder_PropertyType_Alias_When_ModelsBuilderIsEnabled( + string propertyTypeAlias) + { + var propertyType = ContentTypePropertyTypeModel("Test Property", propertyTypeAlias); + var createModel = ContentTypeCreateModel("Test", propertyTypes: new[] { propertyType }); + + var result = await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.Multiple(() => + { + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentTypeOperationStatus.InvalidPropertyTypeAlias, result.Status); + }); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderEnabledTestsBase.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderEnabledTestsBase.cs new file mode 100644 index 0000000000..5709bec3c7 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceModelsBuilderEnabledTestsBase.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Umbraco.Cms.Core.Configuration; +using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Infrastructure.ModelsBuilder.Options; + +namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services; + +public class ContentTypeEditingServiceModelsBuilderEnabledTestsBase : ContentTypeEditingServiceTestsBase +{ + protected override void CustomTestSetup(IUmbracoBuilder builder) + { + builder.Services.ConfigureOptions(); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs index fac26d2dcf..bac636136f 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTests.Create.cs @@ -708,17 +708,6 @@ public partial class ContentTypeEditingServiceTests Assert.AreEqual(ContentTypeOperationStatus.InvalidParent, result.Status); } - // test some properties from IPublishedContent - [TestCase(nameof(IPublishedContent.Id))] - [TestCase(nameof(IPublishedContent.Name))] - [TestCase(nameof(IPublishedContent.SortOrder))] - // test some properties from IPublishedElement - [TestCase(nameof(IPublishedElement.Properties))] - [TestCase(nameof(IPublishedElement.ContentType))] - [TestCase(nameof(IPublishedElement.Key))] - // test some methods from IPublishedContent - [TestCase(nameof(IPublishedContent.IsDraft))] - [TestCase(nameof(IPublishedContent.IsPublished))] [TestCase("")] [TestCase(" ")] [TestCase(" ")] @@ -727,21 +716,12 @@ public partial class ContentTypeEditingServiceTests [TestCase("!\"#¤%&/()=)?`")] public async Task Cannot_Use_Invalid_PropertyType_Alias(string propertyTypeAlias) { - // ensure that property casing is ignored when handling reserved property aliases - var propertyTypeAliases = new[] - { - propertyTypeAlias, propertyTypeAlias.ToLowerInvariant(), propertyTypeAlias.ToUpperInvariant() - }; + var propertyType = ContentTypePropertyTypeModel("Test Property", propertyTypeAlias); + var createModel = ContentTypeCreateModel("Test", propertyTypes: new[] { propertyType }); - foreach (var alias in propertyTypeAliases) - { - var propertyType = ContentTypePropertyTypeModel("Test Property", alias); - var createModel = ContentTypeCreateModel("Test", propertyTypes: new[] { propertyType }); - - var result = await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); - Assert.IsFalse(result.Success); - Assert.AreEqual(ContentTypeOperationStatus.InvalidPropertyTypeAlias, result.Status); - } + var result = await ContentTypeEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey); + Assert.IsFalse(result.Success); + Assert.AreEqual(ContentTypeOperationStatus.InvalidPropertyTypeAlias, result.Status); } [TestCase("testProperty", "testProperty")] @@ -816,9 +796,7 @@ public partial class ContentTypeEditingServiceTests [TestCase(".")] [TestCase("-")] [TestCase("!\"#¤%&/()=)?`")] - [TestCase("system")] - [TestCase("System")] - [TestCase("SYSTEM")] + [TestCaseSource(nameof(DifferentCapitalizedAlias), new object[] { "System"})] public async Task Cannot_Use_Invalid_Alias(string contentTypeAlias) { var createModel = ContentTypeCreateModel("Test", contentTypeAlias); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTestsBase.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTestsBase.cs index 1068f4b9a1..f478904684 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTestsBase.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/ContentTypeEditingServiceTestsBase.cs @@ -180,4 +180,11 @@ public abstract class ContentTypeEditingServiceTestsBase : UmbracoIntegrationTes Type = type, Key = key ?? Guid.NewGuid(), }; + + protected static IEnumerable DifferentCapitalizedAlias(string baseAlias) + { + yield return baseAlias; + yield return baseAlias.ToLowerInvariant(); + yield return baseAlias.ToUpperInvariant(); + } }