diff --git a/src/Umbraco.Core/Models/DataType.cs b/src/Umbraco.Core/Models/DataType.cs index 0c32483fd3..0bb1515950 100644 --- a/src/Umbraco.Core/Models/DataType.cs +++ b/src/Umbraco.Core/Models/DataType.cs @@ -125,11 +125,6 @@ namespace Umbraco.Core.Models } } - public abstract class EditorConfiguration - { - public abstract bool Equals(EditorConfiguration other); - } - /// /// Lazily set the configuration as a serialized json string. /// @@ -141,11 +136,39 @@ namespace Umbraco.Core.Models /// type, and they should be the same. /// Think before using! /// - internal void SetConfiguration(string configurationJson) + internal void SetLazyConfiguration(string configurationJson) { _hasConfiguration = false; _configuration = null; _configurationJson = configurationJson; } + + /// + /// Gets a lazy configuration. + /// + /// + /// The configuration object will be lazily de-serialized. + /// This method is meant to be used when creating published datatypes, exclusively. + /// Think before using! + /// + internal Lazy GetLazyConfiguration() + { + // note: in both cases, make sure we capture what we need - we don't want + // to capture a reference to this full, potentially heavy, DataType instance. + + if (_hasConfiguration) + { + // if configuration has already been de-serialized, return + var capturedConfiguration = _configuration; + return new Lazy(() => capturedConfiguration); + } + else + { + // else, create a Lazy de-serializer + var capturedConfiguration = _configurationJson; + var capturedEditor = _editor; + return new Lazy(() => capturedEditor.ConfigurationEditor.FromDatabase(capturedConfiguration)); + } + } } } diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs index 900bad834e..7603496abd 100644 --- a/src/Umbraco.Core/Models/PropertyType.cs +++ b/src/Umbraco.Core/Models/PropertyType.cs @@ -4,20 +4,19 @@ using System.Reflection; using System.Runtime.Serialization; using System.Text.RegularExpressions; using Umbraco.Core.Models.Entities; -using Umbraco.Core.PropertyEditors; using Umbraco.Core.Strings; namespace Umbraco.Core.Models { /// - /// Defines the type of a object + /// Represents a property type. /// [Serializable] [DataContract(IsReference = true)] [DebuggerDisplay("Id: {Id}, Name: {Name}, Alias: {Alias}")] public class PropertyType : EntityBase, IEquatable { - private static readonly Lazy Ps = new Lazy(); + private static PropertySelectors _selectors; private readonly bool _isExplicitDbType; private string _name; @@ -28,14 +27,13 @@ namespace Umbraco.Core.Models private string _propertyEditorAlias; private ValueStorageType _valueStorageType; private bool _mandatory; - private string _helpText; private int _sortOrder; private string _validationRegExp; private ContentVariation _variations; public PropertyType(IDataType dataType) { - if (dataType == null) throw new ArgumentNullException("dataType"); + if (dataType == null) throw new ArgumentNullException(nameof(dataType)); if(dataType.HasIdentity) _dataTypeId = dataType.Id; @@ -45,10 +43,13 @@ namespace Umbraco.Core.Models _variations = ContentVariation.InvariantNeutral; } + /// + /// Initializes a new instance of the class. + /// public PropertyType(IDataType dataType, string propertyTypeAlias) : this(dataType) { - _alias = GetAlias(propertyTypeAlias); + _alias = SanitizeAlias(propertyTypeAlias); } public PropertyType(string propertyEditorAlias, ValueStorageType valueStorageType) @@ -59,6 +60,8 @@ namespace Umbraco.Core.Models : this(propertyEditorAlias, valueStorageType, false, propertyTypeAlias) { } + // fixme - need to explain and understand this explicitDbType thing here + /// /// Used internally to assign an explicity database type for this property type regardless of what the underlying data type/property editor is. /// @@ -85,79 +88,84 @@ namespace Umbraco.Core.Models _isExplicitDbType = isExplicitDbType; _propertyEditorAlias = propertyEditorAlias; _valueStorageType = valueStorageType; - _alias = GetAlias(propertyTypeAlias); + _alias = SanitizeAlias(propertyTypeAlias); _variations = ContentVariation.InvariantNeutral; } - // ReSharper disable once ClassNeverInstantiated.Local + private static PropertySelectors Selectors => _selectors ?? (_selectors = new PropertySelectors()); + private class PropertySelectors { - public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name); - public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo(x => x.Alias); - public readonly PropertyInfo DescriptionSelector = ExpressionHelper.GetPropertyInfo(x => x.Description); - public readonly PropertyInfo DataTypeDefinitionIdSelector = ExpressionHelper.GetPropertyInfo(x => x.DataTypeId); - public readonly PropertyInfo PropertyEditorAliasSelector = ExpressionHelper.GetPropertyInfo(x => x.PropertyEditorAlias); - public readonly PropertyInfo DataTypeDatabaseTypeSelector = ExpressionHelper.GetPropertyInfo(x => x.ValueStorageType); - public readonly PropertyInfo MandatorySelector = ExpressionHelper.GetPropertyInfo(x => x.Mandatory); - public readonly PropertyInfo HelpTextSelector = ExpressionHelper.GetPropertyInfo(x => x.HelpText); - public readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo(x => x.SortOrder); - public readonly PropertyInfo ValidationRegExpSelector = ExpressionHelper.GetPropertyInfo(x => x.ValidationRegExp); - public readonly PropertyInfo PropertyGroupIdSelector = ExpressionHelper.GetPropertyInfo>(x => x.PropertyGroupId); + public readonly PropertyInfo Name = ExpressionHelper.GetPropertyInfo(x => x.Name); + public readonly PropertyInfo Alias = ExpressionHelper.GetPropertyInfo(x => x.Alias); + public readonly PropertyInfo Description = ExpressionHelper.GetPropertyInfo(x => x.Description); + public readonly PropertyInfo DataTypeId = ExpressionHelper.GetPropertyInfo(x => x.DataTypeId); + public readonly PropertyInfo PropertyEditorAlias = ExpressionHelper.GetPropertyInfo(x => x.PropertyEditorAlias); + public readonly PropertyInfo ValueStorageType = ExpressionHelper.GetPropertyInfo(x => x.ValueStorageType); + public readonly PropertyInfo Mandatory = ExpressionHelper.GetPropertyInfo(x => x.Mandatory); + public readonly PropertyInfo SortOrder = ExpressionHelper.GetPropertyInfo(x => x.SortOrder); + public readonly PropertyInfo ValidationRegExp = ExpressionHelper.GetPropertyInfo(x => x.ValidationRegExp); + public readonly PropertyInfo PropertyGroupId = ExpressionHelper.GetPropertyInfo>(x => x.PropertyGroupId); public readonly PropertyInfo VaryBy = ExpressionHelper.GetPropertyInfo(x => x.Variations); } + /// + /// Gets a value indicating whether the content type, owning this property type, is publishing. + /// public bool IsPublishing { get; internal set; } /// - /// Gets of Sets the Name of the PropertyType + /// Gets of sets the name of the property type. /// [DataMember] public string Name { get => _name; - set => SetPropertyValueAndDetectChanges(value, ref _name, Ps.Value.NameSelector); + set => SetPropertyValueAndDetectChanges(value, ref _name, Selectors.Name); } /// - /// Gets of Sets the Alias of the PropertyType + /// Gets of sets the alias of the property type. /// [DataMember] public string Alias { get => _alias; - set => SetPropertyValueAndDetectChanges(GetAlias(value), ref _alias, Ps.Value.AliasSelector); + set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, Selectors.Alias); } /// - /// Gets of Sets the Description for the PropertyType + /// Gets of sets the description of the property type. /// [DataMember] public string Description { get => _description; - set => SetPropertyValueAndDetectChanges(value, ref _description, Ps.Value.DescriptionSelector); + set => SetPropertyValueAndDetectChanges(value, ref _description, Selectors.Description); } /// - /// Gets of Sets the Id of the DataType (Definition), which the PropertyType is "wrapping" + /// Gets or sets the identifier of the datatype for this property type. /// - /// This is actually the Id of the [DataMember] public int DataTypeId { get => _dataTypeId; - set => SetPropertyValueAndDetectChanges(value, ref _dataTypeId, Ps.Value.DataTypeDefinitionIdSelector); + set => SetPropertyValueAndDetectChanges(value, ref _dataTypeId, Selectors.DataTypeId); } + /// + /// Gets or sets the alias of the property editor for this property type. + /// [DataMember] public string PropertyEditorAlias { get => _propertyEditorAlias; - set => SetPropertyValueAndDetectChanges(value, ref _propertyEditorAlias, Ps.Value.PropertyEditorAliasSelector); + set => SetPropertyValueAndDetectChanges(value, ref _propertyEditorAlias, Selectors.PropertyEditorAlias); } /// - /// Gets or Sets the DatabaseType for which the DataType's value is saved as + /// Gets or sets the database type for storing value for this property type. /// [DataMember] internal ValueStorageType ValueStorageType @@ -167,60 +175,49 @@ namespace Umbraco.Core.Models { //don't allow setting this if an explicit declaration has been made in the ctor if (_isExplicitDbType) return; - SetPropertyValueAndDetectChanges(value, ref _valueStorageType, Ps.Value.DataTypeDatabaseTypeSelector); + SetPropertyValueAndDetectChanges(value, ref _valueStorageType, Selectors.ValueStorageType); } } /// - /// Gets or sets the identifier of the PropertyGroup this PropertyType belongs to. + /// Gets or sets the identifier of the property group this property type belongs to. /// /// For generic properties, the value is null. [DataMember] internal Lazy PropertyGroupId { get => _propertyGroupId; - set => SetPropertyValueAndDetectChanges(value, ref _propertyGroupId, Ps.Value.PropertyGroupIdSelector); + set => SetPropertyValueAndDetectChanges(value, ref _propertyGroupId, Selectors.PropertyGroupId); } /// - /// Gets of Sets the Boolean indicating whether a value for this PropertyType is required + /// Gets of sets a value indicating whether a value for this property type is required. /// [DataMember] public bool Mandatory { get => _mandatory; - set => SetPropertyValueAndDetectChanges(value, ref _mandatory, Ps.Value.MandatorySelector); + set => SetPropertyValueAndDetectChanges(value, ref _mandatory, Selectors.Mandatory); } /// - /// Gets of Sets the Help text for the current PropertyType - /// - [DataMember] - [Obsolete("Not used anywhere, will be removed in future versions")] - public string HelpText - { - get => _helpText; - set => SetPropertyValueAndDetectChanges(value, ref _helpText, Ps.Value.HelpTextSelector); - } - - /// - /// Gets of Sets the Sort order of the PropertyType, which is used for sorting within a group + /// Gets of sets the sort order of the property type. /// [DataMember] public int SortOrder { get => _sortOrder; - set => SetPropertyValueAndDetectChanges(value, ref _sortOrder, Ps.Value.SortOrderSelector); + set => SetPropertyValueAndDetectChanges(value, ref _sortOrder, Selectors.SortOrder); } /// - /// Gets or Sets the RegEx for validation of legacy DataTypes + /// Gets or sets the regular expression for validation of legacy DataTypes fixme?? /// [DataMember] public string ValidationRegExp { get => _validationRegExp; - set => SetPropertyValueAndDetectChanges(value, ref _validationRegExp, Ps.Value.ValidationRegExpSelector); + set => SetPropertyValueAndDetectChanges(value, ref _validationRegExp, Selectors.ValidationRegExp); } /// @@ -229,9 +226,12 @@ namespace Umbraco.Core.Models public ContentVariation Variations { get => _variations; - set => SetPropertyValueAndDetectChanges(value, ref _variations, Ps.Value.VaryBy); + set => SetPropertyValueAndDetectChanges(value, ref _variations, Selectors.VaryBy); } + /// + /// Validates that a variation is valid for the property type. + /// public bool ValidateVariation(int? languageId, string segment, bool throwIfInvalid) { ContentVariation variation; @@ -258,17 +258,6 @@ namespace Umbraco.Core.Models return true; } - private static string GetAlias(string value) - { - //NOTE: WE are doing this because we don't want to do a ToSafeAlias when the alias is the special case of - // being prefixed with Constants.PropertyEditors.InternalGenericPropertiesPrefix - // which is used internally - - return value.StartsWith(Constants.PropertyEditors.InternalGenericPropertiesPrefix) - ? value - : value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase); - } - /// /// Creates a new property of this property type. /// @@ -278,13 +267,12 @@ namespace Umbraco.Core.Models } /// - /// Gets a value indicating whether the value is of the expected type - /// for the property, and can be assigned to the property "as is". + /// Determines whether a value is of the expected type for this property type. /// - /// The value. - /// True if the value is of the expected type for the property, - /// and can be assigned to the property "as is". Otherwise, false, to indicate - /// that some conversion is required. + /// + /// If the value is of the expected type, it can be directly assigned to the property. + /// Otherwise, some conversion is required. + /// public bool IsPropertyTypeValid(object value) { // null values are assumed to be ok @@ -338,10 +326,8 @@ namespace Umbraco.Core.Models } /// - /// Validates the Value from a Property according to the validation settings + /// Determines whether a value is valid for this property type. /// - /// - /// True if valid, otherwise false public bool IsValidPropertyValue(object value) { //If the Property is mandatory and value is null or empty, return false as the validation failed @@ -378,14 +364,27 @@ namespace Umbraco.Core.Models return true; } - public bool Equals(PropertyType other) + /// + /// Sanitizes a property type alias. + /// + private static string SanitizeAlias(string value) { - if (base.Equals(other)) return true; + //NOTE: WE are doing this because we don't want to do a ToSafeAlias when the alias is the special case of + // being prefixed with Constants.PropertyEditors.InternalGenericPropertiesPrefix + // which is used internally - //Check whether the PropertyType's properties are equal. - return Alias.InvariantEquals(other.Alias); + return value.StartsWith(Constants.PropertyEditors.InternalGenericPropertiesPrefix) + ? value + : value.ToCleanString(CleanStringType.Alias | CleanStringType.UmbracoCase); } + /// + public bool Equals(PropertyType other) + { + return other != null && (base.Equals(other) || Alias.InvariantEquals(other.Alias)); + } + + /// public override int GetHashCode() { //Get hash code for the Name field if it is not null. @@ -398,6 +397,7 @@ namespace Umbraco.Core.Models return baseHash ^ hashAlias; } + /// public override object DeepClone() { var clone = (PropertyType)base.DeepClone(); diff --git a/src/Umbraco.Core/Models/PublishedContent/DataTypeConfigurationSource.cs b/src/Umbraco.Core/Models/PublishedContent/DataTypeConfigurationSource.cs deleted file mode 100644 index 15d24fe76b..0000000000 --- a/src/Umbraco.Core/Models/PublishedContent/DataTypeConfigurationSource.cs +++ /dev/null @@ -1,52 +0,0 @@ -using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - -namespace Umbraco.Core.Models.PublishedContent -{ - /// - /// Provides a default implementation. - /// - internal class DataTypeConfigurationSource : IDataTypeConfigurationSource - { - private readonly IDataTypeService _dataTypeService; - private readonly PropertyEditorCollection _propertyEditors; - - // fixme - we might want to have a way to load *all* configs in a fast way? - - /// - /// Initializes a new instance of the class. - /// - /// A data type service. - /// The collection of property editors. - public DataTypeConfigurationSource(IDataTypeService dataTypeService, PropertyEditorCollection propertyEditors) - { - _dataTypeService = dataTypeService; - _propertyEditors = propertyEditors; - } - - /// - public object GetDataTypeConfiguration(string editorAlias, int id) - { - // fixme - this should all be in IDataTypeService - // - // get data type by id / with -or without- configuration - // configuration should just be 1 json field - // could be in uNodeData? - // then, there is no 'get configuration' at all - // - // and then, could be - // if we consider that the published snapshot service in NuCache does a getall - - // fixme - we need a more efficient dataTypeService way of getting these - // fixme - would be nice not to pass editorAlias but annoying for tests? - //var datatype = _dataTypeService.GetDataTypeDefinitionById(id); - //var collection = _dataTypeService.GetPreValuesCollectionByDataTypeId(id); - var dataType = _dataTypeService.GetDataType(id); - return dataType.Configuration; - - // fixme - mapping done in dataTypeService? or should it be on-demand in DataType? - //var editor = _propertyEditors[editorAlias /*datatype.PropertyEditorAlias*/]; - //return editor.MapDataTypeConfiguration(dataType.Configuration); - } - } -} diff --git a/src/Umbraco.Core/Models/PublishedContent/IDataTypeConfigurationSource.cs b/src/Umbraco.Core/Models/PublishedContent/IDataTypeConfigurationSource.cs deleted file mode 100644 index 039dcbaae8..0000000000 --- a/src/Umbraco.Core/Models/PublishedContent/IDataTypeConfigurationSource.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Umbraco.Core.Models.PublishedContent -{ - /// - /// Provides data type configurations. - /// - public interface IDataTypeConfigurationSource - { - /// - /// Gets a data type configuration. - /// - /// The property editor alias. - /// The data type identifier. - /// The data type configuration, as a strongly typed object if the property editor - /// supports it, otherwise as a Dictionary{string, string}. - object GetDataTypeConfiguration(string editorAlias, int id); - } -} diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs index 83d4cca078..ae7fee734e 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContentTypeFactory.cs @@ -26,18 +26,19 @@ /// The published content type owning the property. /// The property type alias. /// The datatype identifier. - /// The property editor alias. FIXME derive from dataTypeId? /// The variations. /// Is used by constructor to create special property types. - PublishedPropertyType CreatePropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, string propertyEditorAlias, ContentVariation variations); + PublishedPropertyType CreatePropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, ContentVariation variations); /// - /// Creates a published data type. + /// Gets a published datatype. /// - /// The data type identifier. - /// The data type editor alias. - /// A published data type with the specified properties. - /// Properties are assumed to be consistent and not checked. - PublishedDataType CreateDataType(int id, string editorAlias); + PublishedDataType GetDataType(int id); + + /// + /// Notifies the factory of datatype changes. + /// + /// This is so the factory can flush its caches. + void NotifyDataTypeChanges(); // fixme never invoked! } } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs index 28ad945267..89f978f417 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Models.PublishedContent foreach ((var alias, (var dataTypeId, var editorAlias)) in BuiltinMemberProperties) { if (aliases.Contains(alias)) continue; - propertyTypes.Add(factory.CreatePropertyType(this, alias, dataTypeId, editorAlias, ContentVariation.InvariantNeutral)); + propertyTypes.Add(factory.CreatePropertyType(this, alias, dataTypeId, ContentVariation.InvariantNeutral)); } } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs index 5a4214eab0..1e349969a6 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentTypeFactory.cs @@ -1,6 +1,9 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using Umbraco.Core.Composing; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; namespace Umbraco.Core.Models.PublishedContent { @@ -11,13 +14,15 @@ namespace Umbraco.Core.Models.PublishedContent { private readonly IPublishedModelFactory _publishedModelFactory; private readonly PropertyValueConverterCollection _propertyValueConverters; - private readonly IDataTypeConfigurationSource _dataTypeConfigurationSource; + private readonly IDataTypeService _dataTypeService; + private readonly object _publishedDataTypesLocker = new object(); + private Dictionary _publishedDataTypes; - public PublishedContentTypeFactory(IPublishedModelFactory publishedModelFactory, PropertyValueConverterCollection propertyValueConverters, IDataTypeConfigurationSource dataTypeConfigurationSource) + public PublishedContentTypeFactory(IPublishedModelFactory publishedModelFactory, PropertyValueConverterCollection propertyValueConverters, IDataTypeService dataTypeService) { _publishedModelFactory = publishedModelFactory; _propertyValueConverters = propertyValueConverters; - _dataTypeConfigurationSource = dataTypeConfigurationSource; + _dataTypeService = dataTypeService; } /// @@ -45,21 +50,47 @@ namespace Umbraco.Core.Models.PublishedContent } /// - public PublishedPropertyType CreatePropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, string propertyEditorAlias, ContentVariation variations = ContentVariation.InvariantNeutral) + public PublishedPropertyType CreatePropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, ContentVariation variations = ContentVariation.InvariantNeutral) { - return new PublishedPropertyType(contentType, propertyTypeAlias, dataTypeId, propertyEditorAlias, true, variations, _propertyValueConverters, _publishedModelFactory, this); + return new PublishedPropertyType(contentType, propertyTypeAlias, dataTypeId, true, variations, _propertyValueConverters, _publishedModelFactory, this); } // for tests - internal PublishedPropertyType CreatePropertyType(string propertyTypeAlias, int dataTypeId, string propertyEditorAlias, bool umbraco = false, ContentVariation variations = ContentVariation.InvariantNeutral) + internal PublishedPropertyType CreatePropertyType(string propertyTypeAlias, int dataTypeId, bool umbraco = false, ContentVariation variations = ContentVariation.InvariantNeutral) { - return new PublishedPropertyType(propertyTypeAlias, dataTypeId, propertyEditorAlias, umbraco, variations, _propertyValueConverters, _publishedModelFactory, this); + return new PublishedPropertyType(propertyTypeAlias, dataTypeId, umbraco, variations, _propertyValueConverters, _publishedModelFactory, this); } /// - public PublishedDataType CreateDataType(int id, string editorAlias) + public PublishedDataType GetDataType(int id) { - return new PublishedDataType(id, editorAlias, _dataTypeConfigurationSource); + Dictionary publishedDataTypes; + lock (_publishedDataTypesLocker) + { + if (_publishedDataTypes == null) + { + var dataTypes = _dataTypeService.GetAll(); + _publishedDataTypes = dataTypes.ToDictionary( + x => x.Id, + x => new PublishedDataType(x.Id, x.EditorAlias, x is DataType d ? d.GetLazyConfiguration() : new Lazy(() => x.Configuration))); + } + + publishedDataTypes = _publishedDataTypes; + } + + if (!publishedDataTypes.TryGetValue(id, out var dataType)) + throw new ArgumentException("Not a valid datatype identifier.", nameof(id)); + + return dataType; + } + + /// + public void NotifyDataTypeChanges() + { + lock (_publishedDataTypesLocker) + { + _publishedDataTypes = null; + } } } } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedDataType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedDataType.cs index d8674c489c..f3f10e63e2 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedDataType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedDataType.cs @@ -12,41 +12,38 @@ namespace Umbraco.Core.Models.PublishedContent /// public class PublishedDataType { - private readonly IDataTypeConfigurationSource _dataTypeConfigurationSource; - private object _configuration; + private readonly Lazy _lazyConfiguration; /// /// Initializes a new instance of the class. /// - internal PublishedDataType(int id, string editorAlias, IDataTypeConfigurationSource dataTypeConfigurationSource) + internal PublishedDataType(int id, string editorAlias, Lazy lazyConfiguration) { - _dataTypeConfigurationSource = dataTypeConfigurationSource ?? throw new ArgumentNullException(nameof(dataTypeConfigurationSource)); + _lazyConfiguration = lazyConfiguration; Id = id; EditorAlias = editorAlias; } /// - /// Gets the data type identifier. + /// Gets the datatype identifier. /// - public int Id { get; } // definition id + public int Id { get; } /// - /// Gets the data type editor alias. + /// Gets the dat type editor alias. /// public string EditorAlias { get; } /// /// Gets the data type configuration. /// - public object Configuration - => _configuration ?? (_configuration = _dataTypeConfigurationSource.GetDataTypeConfiguration(EditorAlias, Id)); + public object Configuration => _lazyConfiguration.Value; /// /// Gets the configuration object. /// /// The expected type of the configuration object. - /// This datatype. /// When the datatype configuration is not of the expected type. public T ConfigurationAs() where T : class diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs index cc2c53a0b4..507e6f7843 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs @@ -31,34 +31,32 @@ namespace Umbraco.Core.Models.PublishedContent /// The new published property type belongs to the published content type. /// public PublishedPropertyType(PublishedContentType contentType, PropertyType propertyType, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory) - : this(propertyType.Alias, propertyType.DataTypeId, propertyType.PropertyEditorAlias, true, propertyType.Variations, propertyValueConverters, publishedModelFactory, factory) + : this(propertyType.Alias, propertyType.DataTypeId, true, propertyType.Variations, propertyValueConverters, publishedModelFactory, factory) { ContentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); } /// - /// Initializes a new instance of the class with specific values. + /// This constructor is for tests and is not intended to be used directly from application code. /// /// - /// This constructor is for tests and is not intended to be used directly from application code. /// Values are assumed to be consisted and are not checked. /// The new published property type belongs to the published content type. /// - public PublishedPropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, string editorAlias, bool isUserProperty, ContentVariation variations, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory) - : this(propertyTypeAlias, dataTypeId, editorAlias, isUserProperty, variations, propertyValueConverters, publishedModelFactory, factory) + public PublishedPropertyType(PublishedContentType contentType, string propertyTypeAlias, int dataTypeId, bool isUserProperty, ContentVariation variations, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory) + : this(propertyTypeAlias, dataTypeId, isUserProperty, variations, propertyValueConverters, publishedModelFactory, factory) { ContentType = contentType ?? throw new ArgumentNullException(nameof(contentType)); } /// - /// Initializes a new instance of the class with specific values. + /// This constructor is for tests and is not intended to be used directly from application code. /// /// - /// This constructor is for tests and is not intended to be used directly from application code. - /// Values are assumed to be consisted and are not checked. + /// Values are assumed to be consistent and are not checked. /// The new published property type does not belong to a published content type. /// - public PublishedPropertyType(string propertyTypeAlias, int dataTypeId, string editorAlias, bool isUserProperty, ContentVariation variations, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory) + public PublishedPropertyType(string propertyTypeAlias, int dataTypeId, bool isUserProperty, ContentVariation variations, PropertyValueConverterCollection propertyValueConverters, IPublishedModelFactory publishedModelFactory, IPublishedContentTypeFactory factory) { _publishedModelFactory = publishedModelFactory ?? throw new ArgumentNullException(nameof(publishedModelFactory)); _propertyValueConverters = propertyValueConverters ?? throw new ArgumentNullException(nameof(propertyValueConverters)); @@ -68,7 +66,7 @@ namespace Umbraco.Core.Models.PublishedContent IsUserProperty = isUserProperty; Variations = variations; - DataType = factory.CreateDataType(dataTypeId, editorAlias); + DataType = factory.GetDataType(dataTypeId); } #endregion diff --git a/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs b/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs index e8ddadd79a..66cbcb354f 100644 --- a/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/DataTypeFactory.cs @@ -32,7 +32,7 @@ namespace Umbraco.Core.Persistence.Factories dataType.Trashed = dto.NodeDto.Trashed; dataType.CreatorId = dto.NodeDto.UserId ?? 0; - dataType.SetConfiguration(dto.Configuration); + dataType.SetLazyConfiguration(dto.Configuration); // reset dirty initial properties (U4-1946) dataType.ResetDirtyProperties(false); diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ImageCropperConfiguration.cs similarity index 77% rename from src/Umbraco.Web/PropertyEditors/ImageCropperConfiguration.cs rename to src/Umbraco.Core/PropertyEditors/ImageCropperConfiguration.cs index b230f48f81..54b69cea45 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperConfiguration.cs +++ b/src/Umbraco.Core/PropertyEditors/ImageCropperConfiguration.cs @@ -1,7 +1,6 @@ using Newtonsoft.Json; -using Umbraco.Core.PropertyEditors; -namespace Umbraco.Web.PropertyEditors +namespace Umbraco.Core.PropertyEditors { /// /// Represents the configuration for the image cropper value editor. @@ -9,9 +8,9 @@ namespace Umbraco.Web.PropertyEditors public class ImageCropperConfiguration { [ConfigurationField("crops", "Crop sizes", "views/propertyeditors/imagecropper/imagecropper.prevalues.html")] - public ImageCropperCrop[] Crops { get; set; } + public Crop[] Crops { get; set; } - public class ImageCropperCrop + public class Crop { [JsonProperty("alias")] public string Alias { get; set; } @@ -23,4 +22,4 @@ namespace Umbraco.Web.PropertyEditors public int Height { get; set; } } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Core/PropertyEditors/ImageCropperEditorConfiguration.cs b/src/Umbraco.Core/PropertyEditors/ImageCropperEditorConfiguration.cs deleted file mode 100644 index f6f8149502..0000000000 --- a/src/Umbraco.Core/PropertyEditors/ImageCropperEditorConfiguration.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; - -namespace Umbraco.Core.PropertyEditors -{ - public class ImageCropperEditorConfiguration - { - [JsonProperty("crops")] - public Crop[] Crops { get; set; } - - public class Crop - { - [JsonProperty("alias")] - public string Alias { get; set; } - - [JsonProperty("width")] - public int Width { get; set; } - - [JsonProperty("height")] - public int Height { get; set; } - } - } -} diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs index dd33bb0dd0..857d22288c 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValue.cs @@ -156,14 +156,14 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters // fixme MOVE TO MODELS O /// Applies a configuration. /// /// Ensures that all crops defined in the configuration exists in the value. - internal void ApplyConfiguration(ImageCropperEditorConfiguration configuration) + internal void ApplyConfiguration(ImageCropperConfiguration configuration) { // merge the crop values - the alias + width + height comes from // configuration, but each crop can store its own coordinates - if (configuration == null) return; + var configuredCrops = configuration?.Crops; + if (configuredCrops == null) return; - var configuredCrops = configuration.Crops; var crops = Crops.ToList(); foreach (var configuredCrop in configuredCrops) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs index 036c3dd4d7..db272269eb 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/ImageCropperValueConverter.cs @@ -47,7 +47,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters value = new ImageCropperValue { Src = sourceString }; } - value.ApplyConfiguration(propertyType.DataType.ConfigurationAs()); + value.ApplyConfiguration(propertyType.DataType.ConfigurationAs()); return value; } diff --git a/src/Umbraco.Core/PropertyEditors/VoidEditor.cs b/src/Umbraco.Core/PropertyEditors/VoidEditor.cs index 429db431fe..8da70c995d 100644 --- a/src/Umbraco.Core/PropertyEditors/VoidEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/VoidEditor.cs @@ -12,10 +12,28 @@ namespace Umbraco.Core.PropertyEditors [HideFromTypeFinder] public class VoidEditor : PropertyEditor { - public VoidEditor(ILogger logger) + /// + /// Initializes a new instance of the class. + /// + /// An optional alias suffix. + /// A logger. + /// The default alias of the editor is "Umbraco.Void". When a suffix is provided, + /// it is appended to the alias. Eg if the suffix is "Foo" the alias is "Umbraco.Void.Foo". + public VoidEditor(string aliasSuffix, ILogger logger) : base(logger) { Alias = "Umbraco.Void"; + if (string.IsNullOrWhiteSpace(aliasSuffix)) return; + Alias += "." + aliasSuffix; } + + /// + /// Initializes a new instance of the class. + /// + /// A logger. + /// The alias of the editor is "Umbraco.Void". + public VoidEditor(ILogger logger) + : this(null, logger) + { } } } diff --git a/src/Umbraco.Core/Runtime/CoreRuntimeComponent.cs b/src/Umbraco.Core/Runtime/CoreRuntimeComponent.cs index 9491614bf4..9265b30655 100644 --- a/src/Umbraco.Core/Runtime/CoreRuntimeComponent.cs +++ b/src/Umbraco.Core/Runtime/CoreRuntimeComponent.cs @@ -104,11 +104,9 @@ namespace Umbraco.Core.Runtime composition.Container.RegisterCollectionBuilder() .Add(f => f.GetInstance().GetPackageActions()); - // need to filter out the ones we dont want!! fixme - what does that mean? composition.Container.RegisterCollectionBuilder() .Append(factory => factory.GetInstance().GetTypes()); - composition.Container.Register(new PerContainerLifetime()); composition.Container.Register(new PerContainerLifetime()); composition.Container.RegisterSingleton(factory diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 3f219bae7a..1f4f45ccfa 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -337,7 +337,7 @@ - + @@ -686,8 +686,6 @@ - - diff --git a/src/Umbraco.Tests.Benchmarks/XmlPublishedContentInitBenchmarks.cs b/src/Umbraco.Tests.Benchmarks/XmlPublishedContentInitBenchmarks.cs index 918c8f55c6..dbb32b18f7 100644 --- a/src/Umbraco.Tests.Benchmarks/XmlPublishedContentInitBenchmarks.cs +++ b/src/Umbraco.Tests.Benchmarks/XmlPublishedContentInitBenchmarks.cs @@ -9,8 +9,11 @@ using BenchmarkDotNet.Horology; using BenchmarkDotNet.Jobs; using Moq; using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using Umbraco.Web.PublishedCache.XmlPublishedCache; namespace Umbraco.Tests.Benchmarks @@ -307,9 +310,19 @@ namespace Umbraco.Tests.Benchmarks private static PublishedContentType GetPublishedContentType(PublishedItemType type, string alias) { - var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + var dataType = new DataType(new VoidEditor(Mock.Of())) { Id = 1 }; + + var dataTypeService = Mock.Of(); + Mock.Get(dataTypeService) + .Setup(x => x.GetDataType(It.IsAny())) + .Returns(id => id == 1 ? dataType : null); + Mock.Get(dataTypeService) + .Setup(x => x.GetAll()) + .Returns(new[] { dataType }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); return factory.CreateContentType(0, alias, new string[] {}, - new List(Enumerable.Range(0, 10).Select(x => factory.CreatePropertyType("prop" + x, 0, "test")))); + new List(Enumerable.Range(0, 10).Select(x => factory.CreatePropertyType("prop" + x, 1)))); } } } diff --git a/src/Umbraco.Tests/Misc/LibraryTests.cs b/src/Umbraco.Tests/Misc/LibraryTests.cs index c6cf2204e2..4732c0365d 100644 --- a/src/Umbraco.Tests/Misc/LibraryTests.cs +++ b/src/Umbraco.Tests/Misc/LibraryTests.cs @@ -12,6 +12,8 @@ using Umbraco.Web; using Umbraco.Web.PublishedCache.XmlPublishedCache; using LightInject; using Moq; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; namespace Umbraco.Tests.Misc { @@ -26,7 +28,10 @@ namespace Umbraco.Tests.Misc { base.SetUp(); - var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); // need to specify a custom callback for unit tests // AutoPublishedContentTypes generates properties automatically @@ -36,7 +41,7 @@ namespace Umbraco.Tests.Misc var propertyTypes = new[] { // AutoPublishedContentType will auto-generate other properties - factory.CreatePropertyType("content", 0, "?"), + factory.CreatePropertyType("content", 1), }; var type = new AutoPublishedContentType(0, "anything", propertyTypes); ContentTypesCache.GetPublishedContentTypeByAlias = (alias) => type; diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 614c4449df..8244cb75ef 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -138,10 +138,6 @@ namespace Umbraco.Tests.Models postedFileMock.Setup(x => x.FileName).Returns("sample.txt"); postedFileMock.Setup(x => x.InputStream).Returns(stream); - // note: must pass a data type service, the "dynamic" SetValue that accepts an object - // arg and does not get a dataTypeService is trying to get the service from app context - var dataTypeService = Mock.Of(); - // Assert content.SetValue("title", postedFileMock.Object); diff --git a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs index d5da545a8e..83d5fea1d1 100644 --- a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs +++ b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs @@ -7,11 +7,17 @@ using NUnit.Framework; using Newtonsoft.Json.Linq; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.IO; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Tests.TestHelpers; using Umbraco.Web.Models; using Umbraco.Web; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.PropertyEditors { @@ -64,9 +70,17 @@ namespace Umbraco.Tests.PropertyEditors container.ConfigureUmbracoCore(); container.RegisterCollectionBuilder(); + container.Register(f => Mock.Of()); + container.Register(f => Mock.Of()); + var mediaFileSystem = new MediaFileSystem(Mock.Of()); + + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of())) { Id = 1 }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); + var converter = new ImageCropperValueConverter(); - var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); - var result = converter.ConvertSourceToIntermediate(null, factory.CreatePropertyType("test", 0, "test"), val1, false); // does not use type for conversion + var result = converter.ConvertSourceToIntermediate(null, factory.CreatePropertyType("test", 1), val1, false); // does not use type for conversion var resultShouldMatch = val2.DeserializeImageCropperValue(); if (expected) diff --git a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs index 5f51d8d5e8..5e7725c3d3 100644 --- a/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/MultiValuePropertyEditorTests.cs @@ -58,11 +58,7 @@ namespace Umbraco.Tests.PropertyEditors Id = 1 }; - var dataTypeService = Mock.Of(); - - Mock.Get(dataTypeService) - .Setup(x => x.GetDataType(It.IsAny())) - .Returns(x => x == 1 ? dataType : null); + var dataTypeService = new TestObjects.TestDataTypeService(dataType); var prop = new Property(1, new PropertyType(dataType)); prop.SetValue("1234,4567,8910"); @@ -89,11 +85,7 @@ namespace Umbraco.Tests.PropertyEditors Id = 1 }; - var dataTypeService = Mock.Of(); - - Mock.Get(dataTypeService) - .Setup(x => x.GetDataType(It.IsAny())) - .Returns(x => x == 1 ? dataType : null); + var dataTypeService = new TestObjects.TestDataTypeService(dataType); var prop = new Property(1, new PropertyType(dataType)); prop.SetValue("1234"); diff --git a/src/Umbraco.Tests/Published/ConvertersTests.cs b/src/Umbraco.Tests/Published/ConvertersTests.cs index 3aa3e11896..bc17a7fb03 100644 --- a/src/Umbraco.Tests/Published/ConvertersTests.cs +++ b/src/Umbraco.Tests/Published/ConvertersTests.cs @@ -6,8 +6,11 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.PublishedCache; @@ -25,11 +28,15 @@ namespace Umbraco.Tests.Published { new SimpleConverter1(), }); - var contentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, Mock.Of()); + + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var contentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); var elementType1 = contentTypeFactory.CreateContentType(1000, "element1", new[] { - contentTypeFactory.CreatePropertyType("prop1", 0, "editor1"), + contentTypeFactory.CreatePropertyType("prop1", 1), }); var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); @@ -40,7 +47,7 @@ namespace Umbraco.Tests.Published private class SimpleConverter1 : IPropertyValueConverter { public bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals("editor1"); + => propertyType.EditorAlias.InvariantEquals("Umbraco.Void"); public Type GetPropertyValueType(PublishedPropertyType propertyType) => typeof (int); @@ -78,11 +85,15 @@ namespace Umbraco.Tests.Published { new SimpleConverter2(publishedSnapshotAccessor), }); - var contentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, Mock.Of()); + + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var contentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); var elementType1 = contentTypeFactory.CreateContentType(1000, "element1", new[] { - contentTypeFactory.CreatePropertyType("prop1", 0, "editor2"), + contentTypeFactory.CreatePropertyType("prop1", 1), }); var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); @@ -106,7 +117,7 @@ namespace Umbraco.Tests.Published } public bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals("editor2"); + => propertyType.EditorAlias.InvariantEquals("Umbraco.Void"); public Type GetPropertyValueType(PublishedPropertyType propertyType) // the first version would be the "generic" version, but say we want to be more precise @@ -160,26 +171,31 @@ namespace Umbraco.Tests.Published Current.Container.Register(f => publishedSnapshotAccessorMock.Object); var converters = Current.Container.GetInstance(); - var contentTypeFactory = new PublishedContentTypeFactory(factory, converters, Mock.Of()); + + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }, + new DataType(new VoidEditor("2", Mock.Of())) { Id = 2 }); + + var contentTypeFactory = new PublishedContentTypeFactory(factory, converters, dataTypeService); var elementType1 = contentTypeFactory.CreateContentType(1000, "element1", new[] { - contentTypeFactory.CreatePropertyType("prop1", 0, "editor1"), + contentTypeFactory.CreatePropertyType("prop1", 1), }); var elementType2 = contentTypeFactory.CreateContentType(1001, "element2", new[] { - contentTypeFactory.CreatePropertyType("prop2", 0, "editor2"), + contentTypeFactory.CreatePropertyType("prop2", 2), }); var contentType1 = contentTypeFactory.CreateContentType(1002, "content1", new[] { - contentTypeFactory.CreatePropertyType("prop1", 0, "editor1"), + contentTypeFactory.CreatePropertyType("prop1", 1), }); var contentType2 = contentTypeFactory.CreateContentType(1003, "content2", new[] { - contentTypeFactory.CreatePropertyType("prop2", 0, "editor2"), + contentTypeFactory.CreatePropertyType("prop2", 2), }); var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "val1" } }, false); @@ -222,7 +238,7 @@ namespace Umbraco.Tests.Published public class SimpleConverter3A : PropertyValueConverterBase { public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias == "editor1"; + => propertyType.EditorAlias == "Umbraco.Void"; public override Type GetPropertyValueType(PublishedPropertyType propertyType) => typeof (string); @@ -241,7 +257,7 @@ namespace Umbraco.Tests.Published } public override bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias == "editor2"; + => propertyType.EditorAlias == "Umbraco.Void.2"; public override Type GetPropertyValueType(PublishedPropertyType propertyType) => typeof (IEnumerable<>).MakeGenericType(ModelType.For("content1")); diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs index 769f16a25c..38832170a3 100644 --- a/src/Umbraco.Tests/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests/Published/NestedContentTests.cs @@ -12,6 +12,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.Models; using Umbraco.Web.PropertyEditors; @@ -63,20 +64,13 @@ namespace Umbraco.Tests.Published } }; - // mocked dataservice returns nested content preValues - var dataTypeService = Mock.Of(); + var dataType3 = new DataType(new TextboxPropertyEditor(logger)) + { + Id = 3 + }; - Mock.Get(dataTypeService) - .Setup(x => x.GetDataType(It.IsAny())) - .Returns(x => - { - switch (x) - { - case 1: return dataType1; - case 2: return dataType2; - default: return null; - } - }); + // mocked dataservice returns nested content preValues + var dataTypeService = new TestObjects.TestDataTypeService(dataType1, dataType2, dataType3); var publishedModelFactory = new Mock(); @@ -130,12 +124,11 @@ namespace Umbraco.Tests.Published new NestedContentManyValueConverter(publishedSnapshotAccessor.Object, publishedModelFactory.Object, proflog), }); - var source = new DataTypeConfigurationSource(dataTypeService, editors); - var factory = new PublishedContentTypeFactory(publishedModelFactory.Object, converters, source); + var factory = new PublishedContentTypeFactory(publishedModelFactory.Object, converters, dataTypeService); - var propertyType1 = factory.CreatePropertyType("property1", 1, Constants.PropertyEditors.Aliases.NestedContent); - var propertyType2 = factory.CreatePropertyType("property2", 2, Constants.PropertyEditors.Aliases.NestedContent); - var propertyTypeN1 = factory.CreatePropertyType("propertyN1", 0, Constants.PropertyEditors.Aliases.Textbox); + var propertyType1 = factory.CreatePropertyType("property1", 1); + var propertyType2 = factory.CreatePropertyType("property2", 2); + var propertyTypeN1 = factory.CreatePropertyType("propertyN1", 3); var contentType1 = factory.CreateContentType(1, "content1", new[] { propertyType1 }); var contentType2 = factory.CreateContentType(2, "content2", new[] { propertyType2 }); diff --git a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs index bf1dc2ca44..49d1707567 100644 --- a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs +++ b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs @@ -4,8 +4,12 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; +using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.PublishedCache; @@ -27,10 +31,13 @@ namespace Umbraco.Tests.Published converter, }); - var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, Mock.Of()); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", new[] { - publishedContentTypeFactory.CreatePropertyType("prop1", 0, "editor1"), + publishedContentTypeFactory.CreatePropertyType("prop1", 1), }); // PublishedElementPropertyBase.GetCacheLevels: @@ -102,10 +109,13 @@ namespace Umbraco.Tests.Published converter, }); - var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, Mock.Of()); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", new[] { - publishedContentTypeFactory.CreatePropertyType("prop1", 0, "editor1"), + publishedContentTypeFactory.CreatePropertyType("prop1", 1), }); var elementsCache = new DictionaryCacheProvider(); @@ -173,10 +183,13 @@ namespace Umbraco.Tests.Published converter, }); - var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, Mock.Of()); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); var setType1 = publishedContentTypeFactory.CreateContentType(1000, "set1", new[] { - publishedContentTypeFactory.CreatePropertyType("prop1", 0, "editor1"), + publishedContentTypeFactory.CreatePropertyType("prop1", 1), }); Assert.Throws(() => @@ -198,7 +211,7 @@ namespace Umbraco.Tests.Published public int InterConverts { get; private set; } public bool IsConverter(PublishedPropertyType propertyType) - => propertyType.EditorAlias.InvariantEquals("editor1"); + => propertyType.EditorAlias.InvariantEquals("Umbraco.Void"); public Type GetPropertyValueType(PublishedPropertyType propertyType) => typeof(int); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index aab1ce64ef..6e7bae28a6 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -6,9 +6,11 @@ using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Composing; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using Umbraco.Web; @@ -121,7 +123,10 @@ namespace Umbraco.Tests.PublishedContent private IPublishedContent GetContent(bool createChildren, int indexVals) { - var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); var contentTypeAlias = createChildren ? "Parent" : "Child"; var d = new TestPublishedContent { @@ -146,8 +151,8 @@ namespace Umbraco.Tests.PublishedContent }; d.Properties = new Collection(new List { - new RawValueProperty(factory.CreatePropertyType("property1", 0, ""), d, "value" + indexVals), - new RawValueProperty(factory.CreatePropertyType("property2", 0, ""), d, "value" + (indexVals + 1)) + new RawValueProperty(factory.CreatePropertyType("property1", 1), d, "value" + indexVals), + new RawValueProperty(factory.CreatePropertyType("property2", 1), d, "value" + (indexVals + 1)) }); if (createChildren) { @@ -163,12 +168,12 @@ namespace Umbraco.Tests.PublishedContent { //create additional columns, used to test the different columns for child nodes ((Collection) d.Properties).Add( - new RawValueProperty(factory.CreatePropertyType("property4", 0, ""), d, "value" + (indexVals + 2))); + new RawValueProperty(factory.CreatePropertyType("property4",1), d, "value" + (indexVals + 2))); } else { ((Collection) d.Properties).Add( - new RawValueProperty(factory.CreatePropertyType("property3", 0, ""), d, "value" + (indexVals + 2))); + new RawValueProperty(factory.CreatePropertyType("property3", 1), d, "value" + (indexVals + 2))); } return d; } diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 7119e8b4c8..5d4e0e1691 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -12,7 +12,11 @@ using Umbraco.Web.Security; using Umbraco.Core.Composing; using Current = Umbraco.Core.Composing.Current; using LightInject; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; +using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; namespace Umbraco.Tests.PublishedContent @@ -191,13 +195,16 @@ namespace Umbraco.Tests.PublishedContent private static SolidPublishedShapshot CreatePublishedSnapshot() { - var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); var caches = new SolidPublishedShapshot(); var cache = caches.InnerContentCache; var props = new[] { - factory.CreatePropertyType("prop1", 1, "?"), + factory.CreatePropertyType("prop1", 1), }; var contentType1 = factory.CreateContentType(1, "ContentType1", Enumerable.Empty(), props); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs index b0fe0bcda4..57d3304e7b 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs @@ -6,6 +6,10 @@ using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Tests.TestHelpers; using LightInject; using Moq; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.PublishedContent { @@ -35,13 +39,17 @@ namespace Umbraco.Tests.PublishedContent base.Initialize(); var converters = Container.GetInstance(); - var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, Mock.Of()); + + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new RichTextPropertyEditor(Mock.Of())) { Id = 1 }); + + var publishedContentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), converters, dataTypeService); // need to specify a custom callback for unit tests var propertyTypes = new[] { // AutoPublishedContentType will auto-generate other properties - publishedContentTypeFactory.CreatePropertyType("content", 0, Constants.PropertyEditors.Aliases.TinyMce), + publishedContentTypeFactory.CreatePropertyType("content", 1), }; var type = new AutoPublishedContentType(0, "anything", propertyTypes); ContentTypesCache.GetPublishedContentTypeByAlias = alias => type; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs index ed7b4aea20..8f6ee5c2b1 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestElements.cs @@ -4,9 +4,11 @@ using System.Linq; using Moq; using Umbraco.Core; using Umbraco.Core.Cache; +using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.PublishedCache; @@ -315,10 +317,16 @@ namespace Umbraco.Tests.PublishedContent class AutoPublishedContentType : PublishedContentType { - private static readonly PublishedContentTypeFactory Factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + private static readonly PublishedPropertyType Default; - private static readonly PublishedPropertyType Default - = Factory.CreatePropertyType("*", 0, "?"); + static AutoPublishedContentType() + { + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 666 }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); + Default = factory.CreatePropertyType("*", 666); + } public AutoPublishedContentType(int id, string alias, IEnumerable propertyTypes) : base(id, alias, PublishedItemType.Content, Enumerable.Empty(), propertyTypes, ContentVariation.InvariantNeutral) diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs index b08376efec..df44a41e27 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTests.cs @@ -10,7 +10,13 @@ using Umbraco.Web; using Umbraco.Web.PublishedCache; using Umbraco.Core.Composing; using LightInject; +using Moq; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using Umbraco.Core.Services; +using Umbraco.Tests.TestHelpers; using Umbraco.Tests.Testing; +using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.PublishedContent { @@ -27,6 +33,16 @@ namespace Umbraco.Tests.PublishedContent Container.RegisterSingleton(f => new PublishedModelFactory(f.GetInstance().GetTypes())); Container.RegisterSingleton(); + + var logger = Mock.Of(); + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(logger)) { Id = 1}, + new DataType(new TrueFalsePropertyEditor(logger)) { Id = 1001 }, + new DataType(new RichTextPropertyEditor(logger)) { Id = 1002 }, + new DataType(new IntegerPropertyEditor(logger)) { Id = 1003 }, + new DataType(new TextboxPropertyEditor(logger)) { Id = 1004 }, + new DataType(new MediaPicker2PropertyEditor(logger)) { Id = 1005 }); + Container.RegisterSingleton(f => dataTypeService); } protected override void Initialize() @@ -43,11 +59,11 @@ namespace Umbraco.Tests.PublishedContent var propertyTypes = new[] { // AutoPublishedContentType will auto-generate other properties - factory.CreatePropertyType("umbracoNaviHide", 0, Constants.PropertyEditors.Aliases.Boolean), - factory.CreatePropertyType("selectedNodes", 0, "?"), - factory.CreatePropertyType("umbracoUrlAlias", 0, "?"), - factory.CreatePropertyType("content", 0, Constants.PropertyEditors.Aliases.TinyMce), - factory.CreatePropertyType("testRecursive", 0, "?"), + factory.CreatePropertyType("umbracoNaviHide", 1001), + factory.CreatePropertyType("selectedNodes", 1), + factory.CreatePropertyType("umbracoUrlAlias", 1), + factory.CreatePropertyType("content", 1002), + factory.CreatePropertyType("testRecursive", 1), }; var compositionAliases = new[] { "MyCompositionAlias" }; var type = new AutoPublishedContentType(0, "anything", compositionAliases, propertyTypes); @@ -553,7 +569,7 @@ namespace Umbraco.Tests.PublishedContent { var factory = Container.GetInstance() as PublishedContentTypeFactory; - var pt = factory.CreatePropertyType("detached", 0, Constants.PropertyEditors.Aliases.Integer); + var pt = factory.CreatePropertyType("detached", 1003); var ct = factory.CreateContentType(0, "alias", new[] { pt }); var prop = new PublishedElementPropertyBase(pt, null, false, PropertyCacheLevel.None, 5548); Assert.IsInstanceOf(prop.GetValue()); @@ -572,9 +588,9 @@ namespace Umbraco.Tests.PublishedContent { var factory = Container.GetInstance() as PublishedContentTypeFactory; - var pt1 = factory.CreatePropertyType("legend", 0, Constants.PropertyEditors.Aliases.Textbox); - var pt2 = factory.CreatePropertyType("image", 0, Constants.PropertyEditors.Aliases.MediaPicker2); - var pt3 = factory.CreatePropertyType("size", 0, Constants.PropertyEditors.Aliases.Integer); + var pt1 = factory.CreatePropertyType("legend", 1004); + var pt2 = factory.CreatePropertyType("image", 1005); + var pt3 = factory.CreatePropertyType("size", 1003); const string val1 = "boom bam"; const int val2 = 0; const int val3 = 666; diff --git a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs index 9cba009f06..16ff6cb46c 100644 --- a/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ b/src/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs @@ -74,7 +74,7 @@ namespace Umbraco.Tests.Scoping var runtimeStateMock = new Mock(); runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run); - var contentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + var contentTypeFactory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); var documentRepository = Mock.Of(); var mediaRepository = Mock.Of(); var memberRepository = Mock.Of(); diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index 4dd0096d5b..0ad95f8ed1 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -6,6 +6,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; @@ -24,7 +25,11 @@ namespace Umbraco.Tests.TestHelpers // need to specify a custom callback for unit tests // AutoPublishedContentTypes generates properties automatically - var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), Mock.Of()); + + var dataTypeService = new TestObjects.TestDataTypeService( + new DataType(new VoidEditor(Mock.Of())) { Id = 1 }); + + var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); var type = new AutoPublishedContentType(0, "anything", new PublishedPropertyType[] { }); ContentTypesCache.GetPublishedContentTypeByAlias = alias => type; } diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs index 410cc36630..6ee99ef582 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs @@ -1,13 +1,16 @@ using System; +using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Web; using LightInject; using Moq; +using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Core.Persistence; using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers.Stubs; @@ -128,8 +131,6 @@ namespace Umbraco.Tests.TestHelpers #region Inner classes - - private class MockDbConnection : DbConnection { protected override DbTransaction BeginDbTransaction(IsolationLevel isolationLevel) @@ -165,6 +166,123 @@ namespace Umbraco.Tests.TestHelpers public override ConnectionState State => ConnectionState.Open; // else NPoco reopens } + public class TestDataTypeService : IDataTypeService + { + public TestDataTypeService() + { + DataTypes = new Dictionary(); + } + + public TestDataTypeService(params IDataType[] dataTypes) + { + DataTypes = dataTypes.ToDictionary(x => x.Id, x => x); + } + + public TestDataTypeService(IEnumerable dataTypes) + { + DataTypes = dataTypes.ToDictionary(x => x.Id, x => x); + } + + public Dictionary DataTypes { get; } + + public Attempt> CreateContainer(int parentId, string name, int userId = 0) + { + throw new NotImplementedException(); + } + + public Attempt SaveContainer(EntityContainer container, int userId = 0) + { + throw new NotImplementedException(); + } + + public EntityContainer GetContainer(int containerId) + { + throw new NotImplementedException(); + } + + public EntityContainer GetContainer(Guid containerId) + { + throw new NotImplementedException(); + } + + public IEnumerable GetContainers(string folderName, int level) + { + throw new NotImplementedException(); + } + + public IEnumerable GetContainers(IDataType dataType) + { + throw new NotImplementedException(); + } + + public IEnumerable GetContainers(int[] containerIds) + { + throw new NotImplementedException(); + } + + public Attempt DeleteContainer(int containerId, int userId = 0) + { + throw new NotImplementedException(); + } + + public Attempt> RenameContainer(int id, string name, int userId = 0) + { + throw new NotImplementedException(); + } + + public IDataType GetDataType(string name) + { + throw new NotImplementedException(); + } + + public IDataType GetDataType(int id) + { + DataTypes.TryGetValue(id, out var dataType); + return dataType; + } + + public IDataType GetDataType(Guid id) + { + throw new NotImplementedException(); + } + + public IEnumerable GetAll(params int[] ids) + { + if (ids.Length == 0) return DataTypes.Values; + return ids.Select(x => DataTypes.TryGetValue(x, out var dataType) ? dataType : null).WhereNotNull(); + } + + public void Save(IDataType dataType, int userId = 0) + { + throw new NotImplementedException(); + } + + public void Save(IEnumerable dataTypeDefinitions, int userId = 0) + { + throw new NotImplementedException(); + } + + public void Save(IEnumerable dataTypeDefinitions, int userId, bool raiseEvents) + { + throw new NotImplementedException(); + } + + public void Delete(IDataType dataType, int userId = 0) + { + throw new NotImplementedException(); + } + + public IEnumerable GetByEditorAlias(string propertyEditorAlias) + { + throw new NotImplementedException(); + } + + public Attempt> Move(IDataType toMove, int parentId) + { + throw new NotImplementedException(); + } + } + #endregion } } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 76c6fa7d44..b37d9ab1f5 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -183,7 +183,6 @@ namespace Umbraco.Tests.Testing Container.RegisterCollectionBuilder(); Container.RegisterSingleton(); - Container.RegisterSingleton(); } protected virtual void ComposeCacheHelper() diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs index c53c6177d0..fcfdddfc7b 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeMapperProfile.cs @@ -197,7 +197,6 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dest => dest.PropertyGroupId, opt => opt.Condition(source => source.GroupId > 0)) .ForMember(dest => dest.PropertyGroupId, opt => opt.MapFrom(display => new Lazy(() => display.GroupId, false))) .ForMember(dest => dest.Key, opt => opt.Ignore()) - .ForMember(dest => dest.HelpText, opt => opt.Ignore()) .ForMember(dest => dest.HasIdentity, opt => opt.Ignore()) //ignore because this is set in the ctor NOT ON UPDATE, STUPID! //.ForMember(type => type.Alias, opt => opt.Ignore()) diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs index f6327a70c2..794a27667b 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs @@ -47,7 +47,7 @@ namespace Umbraco.Web.PropertyEditors var dataType = dataTypeService.GetDataType(propertyType.DataTypeId); if (dataType?.Configuration != null) - value.ApplyConfiguration(dataType.ConfigurationAs()); + value.ApplyConfiguration(dataType.ConfigurationAs()); return value; } @@ -168,7 +168,7 @@ namespace Umbraco.Web.PropertyEditors // more magic here ;-( var configuration = dataTypeService.GetDataType(propertyType.DataTypeId).ConfigurationAs(); - var crops = configuration?.Crops ?? Array.Empty(); + var crops = configuration?.Crops ?? Array.Empty(); return "{src: '" + val + "', crops: " + crops + "}"; } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 7a131f5aa2..17d2e6cc7b 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -249,7 +249,6 @@ -