From 0f0b612de309c518674d9382fab4e33238e2f94b Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 20 Nov 2015 13:39:42 +0100 Subject: [PATCH] Refactor EntityContainer with (sort-of) proper repository --- src/Umbraco.Core/Constants-ObjectTypes.cs | 20 ++ src/Umbraco.Core/Models/EntityContainer.cs | 82 ++++++- .../Repositories/ContentTypeBaseRepository.cs | 47 +--- .../Repositories/ContentTypeRepository.cs | 2 +- .../DataTypeDefinitionRepository.cs | 34 +-- .../Repositories/EntityContainerRepository.cs | 203 +++++++++++------- .../Interfaces/IContentTypeRepository.cs | 17 +- .../IDataTypeDefinitionRepository.cs | 5 +- .../Interfaces/IMediaTypeRepository.cs | 17 +- .../Repositories/MediaTypeRepository.cs | 2 +- .../Persistence/RepositoryFactory.cs | 8 + .../Services/ContentTypeService.cs | 142 ++++++++++-- src/Umbraco.Core/Services/DataTypeService.cs | 73 ++++++- .../Services/IContentTypeService.cs | 12 +- src/Umbraco.Core/Services/IDataTypeService.cs | 3 + .../Repositories/ContentTypeRepositoryTest.cs | 81 ++++--- .../DataTypeDefinitionRepositoryTest.cs | 67 +++--- .../Repositories/MediaTypeRepositoryTest.cs | 67 +++--- .../Entities/MockedContentTypes.cs | 29 ++- 19 files changed, 600 insertions(+), 311 deletions(-) diff --git a/src/Umbraco.Core/Constants-ObjectTypes.cs b/src/Umbraco.Core/Constants-ObjectTypes.cs index 4600ad0fb4..560cd4b306 100644 --- a/src/Umbraco.Core/Constants-ObjectTypes.cs +++ b/src/Umbraco.Core/Constants-ObjectTypes.cs @@ -14,16 +14,31 @@ namespace Umbraco.Core /// public const string DataTypeContainer = "521231E3-8B37-469C-9F9D-51AFC91FEB7B"; + /// + /// Guid for a data type container + /// + public static readonly Guid DataTypeContainerGuid = new Guid(DataTypeContainer); + /// /// Guid for a doc type container /// public const string DocumentTypeContainer = "2F7A2769-6B0B-4468-90DD-AF42D64F7F16"; + /// + /// Guid for a doc type container + /// + public static readonly Guid DocumentTypeContainerGuid = new Guid(DocumentTypeContainer); + /// /// Guid for a doc type container /// public const string MediaTypeContainer = "42AEF799-B288-4744-9B10-BE144B73CDC4"; + /// + /// Guid for a doc type container + /// + public static readonly Guid MediaTypeContainerGuid = new Guid(MediaTypeContainer); + /// /// Guid for a Content Item object. /// @@ -44,6 +59,11 @@ namespace Umbraco.Core /// public const string DataType = "30A2A501-1978-4DDB-A57B-F7EFED43BA3C"; + /// + /// Guid for a DataType object. + /// + public static readonly Guid DataTypeGuid = new Guid(DataType); + /// /// Guid for a Document object. /// diff --git a/src/Umbraco.Core/Models/EntityContainer.cs b/src/Umbraco.Core/Models/EntityContainer.cs index 4cfbe090ee..92965bf238 100644 --- a/src/Umbraco.Core/Models/EntityContainer.cs +++ b/src/Umbraco.Core/Models/EntityContainer.cs @@ -1,25 +1,93 @@ using System; -using Umbraco.Core.Models.EntityBase; +using System.Collections.Generic; +using System.Linq; namespace Umbraco.Core.Models { /// - /// Represents a folder for organizing entities such as content types and data types + /// Represents a folder for organizing entities such as content types and data types. /// - public sealed class EntityContainer : UmbracoEntity, IAggregateRoot + public sealed class EntityContainer : UmbracoEntity { - public EntityContainer() - { + private readonly Guid _containedObjectType; + + private static readonly Dictionary ObjectTypeMap = new Dictionary + { + { Constants.ObjectTypes.DataTypeGuid, Constants.ObjectTypes.DataTypeContainerGuid }, + { Constants.ObjectTypes.DocumentTypeGuid, Constants.ObjectTypes.DocumentTypeContainerGuid }, + { Constants.ObjectTypes.MediaTypeGuid, Constants.ObjectTypes.MediaTypeContainerGuid } + }; + + /// + /// Initializes a new instance of an class. + /// + public EntityContainer(Guid containedObjectType) + { + if (ObjectTypeMap.ContainsKey(containedObjectType) == false) + throw new ArgumentException("Not a contained object type.", "containedObjectType"); + _containedObjectType = containedObjectType; + + ParentId = -1; + Path = "-1"; + Level = 0; + SortOrder = 0; } - public EntityContainer(int id, Guid uniqueId, int parentId, string name, int userId, string path) + /// + /// Initializes a new instance of an class. + /// + internal EntityContainer(int id, Guid uniqueId, int parentId, string path, int level, int sortOrder, Guid containedObjectType, string name, int userId) + : this(containedObjectType) { Id = id; Key = uniqueId; ParentId = parentId; Name = name; - CreatorId = userId; Path = path; + Level = level; + SortOrder = sortOrder; + CreatorId = userId; + } + + /// + /// Gets or sets the node object type of the contained objects. + /// + public Guid ContainedObjectType + { + get { return _containedObjectType; } + } + + /// + /// Gets the node object type of the container objects. + /// + public Guid ContainerObjectType + { + get { return ObjectTypeMap[_containedObjectType]; } + } + + /// + /// Gets the container object type corresponding to a contained object type. + /// + /// The contained object type. + /// The object type of containers containing objects of the contained object type. + public static Guid GetContainerObjectType(Guid containedObjectType) + { + if (ObjectTypeMap.ContainsKey(containedObjectType) == false) + throw new ArgumentException("Not a contained object type.", "containedObjectType"); + return ObjectTypeMap[containedObjectType]; + } + + /// + /// Gets the contained object type corresponding to a container object type. + /// + /// The container object type. + /// The object type of objects that containers of the container object type can contain. + public static Guid GetContainedObjectType(Guid containerObjectType) + { + var contained = ObjectTypeMap.FirstOrDefault(x => x.Value == containerObjectType).Key; + if (contained == null) + throw new ArgumentException("Not a container object type.", "containerObjectType"); + return contained; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs index 986a24b9db..5ed0f62124 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs @@ -30,38 +30,25 @@ namespace Umbraco.Core.Persistence.Repositories internal abstract class ContentTypeBaseRepository : PetaPocoRepositoryBase, IReadRepository where TEntity : class, IContentTypeComposition { - - protected ContentTypeBaseRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, - Guid containerType) - : base(work, cache, logger, sqlSyntax) - { - _guidRepo = new GuidReadOnlyContentTypeBaseRepository(this, work, cache, logger, sqlSyntax); - ContainerRepository = new EntityContainerRepository(work, cache, logger, sqlSyntax, containerType, NodeObjectTypeId); - } - protected ContentTypeBaseRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) : base(work, cache, logger, sqlSyntax) { _guidRepo = new GuidReadOnlyContentTypeBaseRepository(this, work, cache, logger, sqlSyntax); - ContainerRepository = null; } - protected EntityContainerRepository ContainerRepository { get; private set; } private readonly GuidReadOnlyContentTypeBaseRepository _guidRepo; - public IEnumerable> Move(TEntity toMove, int parentId) + public IEnumerable> Move(TEntity toMove, EntityContainer container) { - if (parentId > 0) + var parentId = -1; + if (container != null) { - var container = ContainerRepository.Get(parentId); - if (container == null) - throw new DataOperationException(MoveOperationStatusType.FailedParentNotFound); - // Check on paths if ((string.Format(",{0},", container.Path)).IndexOf(string.Format(",{0},", toMove.Id), StringComparison.Ordinal) > -1) { throw new DataOperationException(MoveOperationStatusType.FailedNotAllowedByPath); } + parentId = container.Id; } //used to track all the moved entities to be given to the event @@ -91,32 +78,6 @@ namespace Umbraco.Core.Persistence.Repositories return moveInfo; } - /// - /// Deletes a folder - this will move all contained entities into their parent - /// - /// - public void DeleteContainer(int containerId) - { - if (ContainerRepository == null) throw new NotSupportedException("The repository type " + GetType() + " does not support containers"); - - var found = ContainerRepository.Get(containerId); - ContainerRepository.Delete(found); - } - - public EntityContainer CreateContainer(int parentId, string name, int userId) - { - if (ContainerRepository == null) throw new NotSupportedException("The repository type " + GetType() + " does not support containers"); - - var container = new EntityContainer - { - ParentId = parentId, - Name = name, - CreatorId = userId - }; - ContainerRepository.AddOrUpdate(container); - return container; - } - /// /// Returns the content type ids that match the query /// diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs index 9899a765dc..6d8f73725c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeRepository.cs @@ -25,7 +25,7 @@ namespace Umbraco.Core.Persistence.Repositories private readonly ITemplateRepository _templateRepository; public ContentTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, ITemplateRepository templateRepository) - : base(work, cache, logger, sqlSyntax, new Guid(Constants.ObjectTypes.DocumentTypeContainer)) + : base(work, cache, logger, sqlSyntax) { _templateRepository = templateRepository; } diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index a72582acae..499e2ba849 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -29,7 +29,6 @@ namespace Umbraco.Core.Persistence.Repositories private readonly CacheHelper _cacheHelper; private readonly IContentTypeRepository _contentTypeRepository; private readonly DataTypePreValueRepository _preValRepository; - private readonly EntityContainerRepository _containerRepository; public DataTypeDefinitionRepository(IDatabaseUnitOfWork work, CacheHelper cache, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax, IContentTypeRepository contentTypeRepository) @@ -38,29 +37,6 @@ namespace Umbraco.Core.Persistence.Repositories _cacheHelper = cacheHelper; _contentTypeRepository = contentTypeRepository; _preValRepository = new DataTypePreValueRepository(work, CacheHelper.CreateDisabledCacheHelper(), logger, sqlSyntax); - _containerRepository = new EntityContainerRepository(work, cache, logger, sqlSyntax, new Guid(Constants.ObjectTypes.DataTypeContainer), NodeObjectTypeId); - } - - /// - /// Deletes a folder - this will move all contained entities into their parent - /// - /// - public void DeleteContainer(int containerId) - { - var found = _containerRepository.Get(containerId); - _containerRepository.Delete(found); - } - - public EntityContainer CreateContainer(int parentId, string name, int userId) - { - var container = new EntityContainer - { - ParentId = parentId, - Name = name, - CreatorId = userId - }; - _containerRepository.AddOrUpdate(container); - return container; } #region Overrides of RepositoryBase @@ -355,19 +331,17 @@ AND umbracoNode.id <> @id", AddOrUpdatePreValues(dtd, values); } - public IEnumerable> Move(IDataTypeDefinition toMove, int parentId) + public IEnumerable> Move(IDataTypeDefinition toMove, EntityContainer container) { - if (parentId > 0) + var parentId = -1; + if (container != null) { - var container = _containerRepository.Get(parentId); - if (container == null) - throw new DataOperationException(MoveOperationStatusType.FailedParentNotFound); - // Check on paths if ((string.Format(",{0},", container.Path)).IndexOf(string.Format(",{0},", toMove.Id), StringComparison.Ordinal) > -1) { throw new DataOperationException(MoveOperationStatusType.FailedNotAllowedByPath); } + parentId = container.Id; } //used to track all the moved entities to be given to the event diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs index fd368a0685..6fd5045e04 100644 --- a/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/EntityContainerRepository.cs @@ -14,23 +14,13 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { /// - /// An internal repository for managing entity containers such as doc type, media type, data type containers + /// An internal repository for managing entity containers such as doc type, media type, data type containers. /// - /// - /// All we're supporting here is a single get, creating and deleting - /// internal class EntityContainerRepository : PetaPocoRepositoryBase { - private readonly Guid _containerObjectType; - private readonly Guid _entityObjectType; - - public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax, - Guid containerObjectType, Guid entityObjectType) + public EntityContainerRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) : base(work, cache, logger, sqlSyntax) - { - _containerObjectType = containerObjectType; - _entityObjectType = entityObjectType; - } + { } /// /// Do not cache anything @@ -42,22 +32,19 @@ namespace Umbraco.Core.Persistence.Repositories protected override EntityContainer PerformGet(int id) { - var sql = GetBaseQuery(false); - sql.Where(GetBaseWhereClause(), new { Id = id, NodeObjectType = _containerObjectType }); + var sql = GetBaseQuery(false).Where(GetBaseWhereClause(), new { id }); - var containerDto = Database.Fetch(sql).FirstOrDefault(); - if (containerDto == null) - return null; + var nodeDto = Database.Fetch(sql).FirstOrDefault(); + return nodeDto == null ? null : CreateEntity(nodeDto); + } - var entity = new EntityContainer(containerDto.NodeId, containerDto.UniqueId, - containerDto.ParentId, containerDto.Text, containerDto.UserId ?? 0, - containerDto.Path); + // temp - so we don't have to implement GetByQuery + public EntityContainer Get(Guid id) + { + var sql = GetBaseQuery(false).Where("UniqueId=@uniqueId", new { uniqueId = id }); - //on initial construction we don't want to have dirty properties tracked - // http://issues.umbraco.org/issue/U4-1946 - entity.ResetDirtyProperties(false); - - return entity; + var nodeDto = Database.Fetch(sql).FirstOrDefault(); + return nodeDto == null ? null : CreateEntity(nodeDto); } protected override IEnumerable PerformGetAll(params int[] ids) @@ -70,6 +57,26 @@ namespace Umbraco.Core.Persistence.Repositories throw new NotImplementedException(); } + private static EntityContainer CreateEntity(NodeDto nodeDto) + { + if (nodeDto.NodeObjectType.HasValue == false) + throw new InvalidOperationException("Node with id " + nodeDto.NodeId + " has no object type."); + + // throws if node is not a container + var containedObjectType = EntityContainer.GetContainedObjectType(nodeDto.NodeObjectType.Value); + + var entity = new EntityContainer(nodeDto.NodeId, nodeDto.UniqueId, + nodeDto.ParentId, nodeDto.Path, nodeDto.Level, nodeDto.SortOrder, + containedObjectType, + nodeDto.Text, nodeDto.UserId ?? 0); + + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + entity.ResetDirtyProperties(false); + + return entity; + } + protected override Sql GetBaseQuery(bool isCount) { var sql = new Sql(); @@ -86,7 +93,7 @@ namespace Umbraco.Core.Persistence.Repositories protected override string GetBaseWhereClause() { - return "umbracoNode.id = @Id and nodeObjectType = @NodeObjectType"; + return "umbracoNode.id = @id"; //" and nodeObjectType = @NodeObjectType"; } protected override IEnumerable GetDeleteClauses() @@ -96,98 +103,150 @@ namespace Umbraco.Core.Persistence.Repositories protected override Guid NodeObjectTypeId { - get { return _containerObjectType; } + get { throw new NotImplementedException(); } } protected override void PersistDeletedItem(EntityContainer entity) { - var exists = Database.FirstOrDefault( - new Sql().Select("*") - .From(SqlSyntax) - .Where(dto => dto.NodeId == entity.Id && dto.NodeObjectType == _containerObjectType)); + var nodeDto = Database.FirstOrDefault(new Sql().Select("*") + .From(SqlSyntax) + .Where(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType)); - if (exists == null) return; + if (nodeDto == null) return; - //We need to move the content types and folders that exist under this folder to it's parent folder - var children = Database.Fetch( - new Sql().Select("*") - .From(SqlSyntax) - .Where("parentID=@parentID AND (nodeObjectType=@entityObjectType OR nodeObjectType=@containerObjectType)", - new {parentID = entity.Id, entityObjectType = _entityObjectType, containerObjectType = _containerObjectType})); + // move children to the parent so they are not orphans + var childDtos = Database.Fetch(new Sql().Select("*") + .From(SqlSyntax) + .Where("parentID=@parentID AND (nodeObjectType=@containedObjectType OR nodeObjectType=@containerObjectType)", + new + { + parentID = entity.Id, + containedObjectType = entity.ContainedObjectType, + containerObjectType = entity.ContainerObjectType + })); - foreach (var childDto in children) + foreach (var childDto in childDtos) { - childDto.ParentId = exists.ParentId; + childDto.ParentId = nodeDto.ParentId; Database.Update(childDto); } - //now that everything is moved up a level, we need to delete the container - Database.Delete(exists); + // delete + Database.Delete(nodeDto); } protected override void PersistNewItem(EntityContainer entity) { entity.Name = entity.Name.Trim(); - Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name"); - var exists = Database.FirstOrDefault( - new Sql().Select("*") - .From(SqlSyntax) - .Where(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == _containerObjectType)); - - if (exists != null) - { - throw new InvalidOperationException("A folder with the same name already exists"); - } + // guard against duplicates + var nodeDto = Database.FirstOrDefault(new Sql().Select("*") + .From(SqlSyntax) + .Where(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType)); + if (nodeDto != null) + throw new InvalidOperationException("A container with the same name already exists."); + // create var level = 0; var path = "-1"; if (entity.ParentId > -1) { - var parent = Database.FirstOrDefault( - new Sql().Select("*") - .From(SqlSyntax) - .Where(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == _containerObjectType)); + var parentDto = Database.FirstOrDefault(new Sql().Select("*") + .From(SqlSyntax) + .Where(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType)); - if (parent == null) - { - throw new NullReferenceException("No content type container found with parent id " + entity.ParentId); - } - level = parent.Level; - path = parent.Path; + if (parentDto == null) + throw new NullReferenceException("Could not find parent container with id " + entity.ParentId); + + level = parentDto.Level; + path = parentDto.Path; } - var nodeDto = new NodeDto + // note: sortOrder is NOT managed and always zero for containers + + nodeDto = new NodeDto { CreateDate = DateTime.Now, Level = Convert.ToInt16(level + 1), - NodeObjectType = _containerObjectType, + NodeObjectType = entity.ContainerObjectType, ParentId = entity.ParentId, Path = path, SortOrder = 0, Text = entity.Name, - Trashed = false, - UniqueId = Guid.NewGuid(), UserId = entity.CreatorId }; - var id = Convert.ToInt32(Database.Insert(nodeDto)); + if (entity.Key != default(Guid)) + nodeDto.UniqueId = entity.Key; - //update the path + // insert, get the id, update the path with the id + var id = Convert.ToInt32(Database.Insert(nodeDto)); nodeDto.Path = nodeDto.Path + "," + nodeDto.NodeId; Database.Save(nodeDto); + // refresh the entity entity.Id = id; + entity.Key = nodeDto.UniqueId; entity.Path = nodeDto.Path; - + entity.Level = nodeDto.Level; + entity.SortOrder = 0; + entity.CreateDate = nodeDto.CreateDate; entity.ResetDirtyProperties(); } + // beware! does NOT manage descendants in case of a new parent + // protected override void PersistUpdatedItem(EntityContainer entity) { - // note: don't forget to handle UniqueID! - throw new NotImplementedException(); + entity.Name = entity.Name.Trim(); + Mandate.ParameterNotNullOrEmpty(entity.Name, "entity.Name"); + + // find container to update + var nodeDto = Database.FirstOrDefault(new Sql().Select("*") + .From(SqlSyntax) + .Where(dto => dto.NodeId == entity.Id && dto.NodeObjectType == entity.ContainerObjectType)); + if (nodeDto == null) + throw new InvalidOperationException("Could not find container with id " + entity.Id); + + // guard against duplicates + var dupNodeDto = Database.FirstOrDefault(new Sql().Select("*") + .From(SqlSyntax) + .Where(dto => dto.ParentId == entity.ParentId && dto.Text == entity.Name && dto.NodeObjectType == entity.ContainerObjectType)); + if (dupNodeDto != null && dupNodeDto.NodeId != nodeDto.NodeId) + throw new InvalidOperationException("A container with the same name already exists."); + + // update + nodeDto.Text = entity.Name; + if (nodeDto.ParentId != entity.ParentId) + { + nodeDto.Level = 0; + nodeDto.Path = "-1"; + if (entity.ParentId > -1) + { + var parent = Database.FirstOrDefault(new Sql().Select("*") + .From(SqlSyntax) + .Where(dto => dto.NodeId == entity.ParentId && dto.NodeObjectType == entity.ContainerObjectType)); + + if (parent == null) + throw new NullReferenceException("Could not find parent container with id " + entity.ParentId); + + nodeDto.Level = Convert.ToInt16(parent.Level + 1); + nodeDto.Path = parent.Path + "," + nodeDto.NodeId; + } + nodeDto.ParentId = entity.ParentId; + } + + // note: sortOrder is NOT managed and always zero for containers + + // update + Database.Update(nodeDto); + + // refresh the entity + entity.Path = nodeDto.Path; + entity.Level = nodeDto.Level; + entity.SortOrder = 0; + entity.ResetDirtyProperties(); } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentTypeRepository.cs index 9a90af21d6..625023fd9e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentTypeRepository.cs @@ -21,21 +21,6 @@ namespace Umbraco.Core.Persistence.Repositories /// IEnumerable GetAllPropertyTypeAliases(); - /// - /// Creates a folder for content types - /// - /// - /// - /// - /// - EntityContainer CreateContainer(int parentId, string name, int userId); - - /// - /// Deletes a folder - this will move all contained content types into their parent - /// - /// - void DeleteContainer(int containerId); - - IEnumerable> Move(IContentType toMove, int parentId); + IEnumerable> Move(IContentType toMove, EntityContainer container); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDataTypeDefinitionRepository.cs index 2ae9dfe551..6d7265f717 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IDataTypeDefinitionRepository.cs @@ -7,14 +7,11 @@ namespace Umbraco.Core.Persistence.Repositories { public interface IDataTypeDefinitionRepository : IRepositoryQueryable { - EntityContainer CreateContainer(int parentId, string name, int userId); - void DeleteContainer(int containerId); - PreValueCollection GetPreValuesCollectionByDataTypeId(int dataTypeId); string GetPreValueAsString(int preValueId); void AddOrUpdatePreValues(IDataTypeDefinition dataType, IDictionary values); void AddOrUpdatePreValues(int dataTypeId, IDictionary values); - IEnumerable> Move(IDataTypeDefinition toMove, int parentId); + IEnumerable> Move(IDataTypeDefinition toMove, EntityContainer container); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs index 17073d18b3..6d9331a22a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMediaTypeRepository.cs @@ -15,21 +15,6 @@ namespace Umbraco.Core.Persistence.Repositories /// An enumerable list of objects IEnumerable GetByQuery(IQuery query); - /// - /// Creates a folder for content types - /// - /// - /// - /// - /// - EntityContainer CreateContainer(int parentId, string name, int userId); - - /// - /// Deletes a folder - this will move all contained content types into their parent - /// - /// - void DeleteContainer(int folderId); - - IEnumerable> Move(IMediaType toMove, int parentId); + IEnumerable> Move(IMediaType toMove, EntityContainer container); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs index fcdfaf456d..3616a145ce 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaTypeRepository.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Repositories { public MediaTypeRepository(IDatabaseUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax) - : base(work, cache, logger, sqlSyntax, new Guid(Constants.ObjectTypes.MediaTypeContainer)) + : base(work, cache, logger, sqlSyntax) { } diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index f9367d8433..69ca5f78e2 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -303,5 +303,13 @@ namespace Umbraco.Core.Persistence CacheHelper.CreateDisabledCacheHelper(), //never cache _logger, _sqlSyntax); } + + internal virtual EntityContainerRepository CreateEntityContainerRepository(IDatabaseUnitOfWork uow) + { + return new EntityContainerRepository( + uow, + _cacheHelper, + _logger, _sqlSyntax); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index eccdae1ab8..eff7202201 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -41,14 +41,22 @@ namespace Umbraco.Core.Services _mediaService = mediaService; } + #region Containers + public Attempt CreateContentTypeContainer(int parentId, string name, int userId = 0) { var uow = UowProvider.GetUnitOfWork(); - using (var repo = RepositoryFactory.CreateContentTypeRepository(uow)) + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) { try { - var container = repo.CreateContainer(parentId, name, userId); + var container = new EntityContainer(Constants.ObjectTypes.DocumentTypeGuid) + { + Name = name, + ParentId = parentId, + CreatorId = userId + }; + repo.AddOrUpdate(container); uow.Commit(); return Attempt.Succeed(container.Id); } @@ -63,15 +71,21 @@ namespace Umbraco.Core.Services public Attempt CreateMediaTypeContainer(int parentId, string name, int userId = 0) { var uow = UowProvider.GetUnitOfWork(); - using (var repo = RepositoryFactory.CreateMediaTypeRepository(uow)) + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) { try { - var container = repo.CreateContainer(parentId, name, userId); + var container = new EntityContainer(Constants.ObjectTypes.MediaTypeGuid) + { + Name = name, + ParentId = parentId, + CreatorId = userId + }; + repo.AddOrUpdate(container); uow.Commit(); return Attempt.Succeed(container.Id); } - catch (System.Exception ex) + catch (Exception ex) { return Attempt.Fail(ex); } @@ -79,28 +93,106 @@ namespace Umbraco.Core.Services } } - public void DeleteContentTypeContainer(int folderId, int userId = 0) + public void SaveContentTypeContainer(EntityContainer container, int userId = 0) { + SaveContainer(container, Constants.ObjectTypes.DocumentTypeGuid, "document type", userId); + } + + public void SaveMediaTypeContainer(EntityContainer container, int userId = 0) + { + SaveContainer(container, Constants.ObjectTypes.MediaTypeGuid, "media type", userId); + } + + private void SaveContainer(EntityContainer container, Guid containedObjectType, string objectTypeName, int userId) + { + if (container.ContainedObjectType != containedObjectType) + throw new InvalidOperationException("Not a " + objectTypeName + " container."); + if (container.HasIdentity && container.IsPropertyDirty("ParentId")) + throw new InvalidOperationException("Cannot save a container with a modified parent, move the container instead."); + var uow = UowProvider.GetUnitOfWork(); - using (var repo = RepositoryFactory.CreateContentTypeRepository(uow)) + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) { - repo.DeleteContainer(folderId); + repo.AddOrUpdate(container); uow.Commit(); //TODO: Audit trail ? } } - public void DeleteMediaTypeContainer(int folderId, int userId = 0) + public EntityContainer GetContentTypeContainer(int containerId) + { + return GetContainer(containerId, Constants.ObjectTypes.DocumentTypeGuid); + } + + public EntityContainer GetMediaTypeContainer(int containerId) + { + return GetContainer(containerId, Constants.ObjectTypes.MediaTypeGuid); + } + + private EntityContainer GetContainer(int containerId, Guid containedObjectType) { var uow = UowProvider.GetUnitOfWork(); - using (var repo = RepositoryFactory.CreateMediaTypeRepository(uow)) + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) { - repo.DeleteContainer(folderId); + var container = repo.Get(containerId); + return container != null && container.ContainedObjectType == containedObjectType + ? container + : null; + } + } + + public EntityContainer GetContentTypeContainer(Guid containerId) + { + return GetContainer(containerId, Constants.ObjectTypes.DocumentTypeGuid); + } + + public EntityContainer GetMediaTypeContainer(Guid containerId) + { + return GetContainer(containerId, Constants.ObjectTypes.MediaTypeGuid); + } + + private EntityContainer GetContainer(Guid containerId, Guid containedObjectType) + { + var uow = UowProvider.GetUnitOfWork(); + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) + { + var container = repo.Get(containerId); + return container != null && container.ContainedObjectType == containedObjectType + ? container + : null; + } + } + + public void DeleteContentTypeContainer(int containerId, int userId = 0) + { + var uow = UowProvider.GetUnitOfWork(); + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) + { + var container = repo.Get(containerId); + if (container == null) return; + if (container.ContainedObjectType != Constants.ObjectTypes.DocumentTypeGuid) return; + repo.Delete(container); uow.Commit(); //TODO: Audit trail ? } } + public void DeleteMediaTypeContainer(int containerId, int userId = 0) + { + var uow = UowProvider.GetUnitOfWork(); + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) + { + var container = repo.Get(containerId); + if (container == null) return; + if (container.ContainedObjectType != Constants.ObjectTypes.MediaTypeGuid) return; + repo.Delete(container); + uow.Commit(); + //TODO: Audit trail ? + } + } + + #endregion + /// /// Gets all property type aliases. /// @@ -712,12 +804,12 @@ namespace Umbraco.Core.Services } } - public Attempt> MoveMediaType(IMediaType toMove, int parentId) + public Attempt> MoveMediaType(IMediaType toMove, int containerId) { var evtMsgs = EventMessagesFactory.Get(); if (MovingMediaType.IsRaisedEventCancelled( - new MoveEventArgs(evtMsgs, new MoveEventInfo(toMove, toMove.Path, parentId)), + new MoveEventArgs(evtMsgs, new MoveEventInfo(toMove, toMove.Path, containerId)), this)) { return Attempt.Fail( @@ -727,11 +819,19 @@ namespace Umbraco.Core.Services var moveInfo = new List>(); var uow = UowProvider.GetUnitOfWork(); + using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow)) using (var repository = RepositoryFactory.CreateMediaTypeRepository(uow)) { try { - moveInfo.AddRange(repository.Move(toMove, parentId)); + EntityContainer container = null; + if (containerId > 0) + { + container = containerRepository.Get(containerId); + if (container == null || container.ContainedObjectType != Constants.ObjectTypes.MediaTypeGuid) + throw new DataOperationException(MoveOperationStatusType.FailedParentNotFound); + } + moveInfo.AddRange(repository.Move(toMove, container)); } catch (DataOperationException ex) { @@ -747,12 +847,12 @@ namespace Umbraco.Core.Services new OperationStatus(MoveOperationStatusType.Success, evtMsgs)); } - public Attempt> MoveContentType(IContentType toMove, int parentId) + public Attempt> MoveContentType(IContentType toMove, int containerId) { var evtMsgs = EventMessagesFactory.Get(); if (MovingContentType.IsRaisedEventCancelled( - new MoveEventArgs(evtMsgs, new MoveEventInfo(toMove, toMove.Path, parentId)), + new MoveEventArgs(evtMsgs, new MoveEventInfo(toMove, toMove.Path, containerId)), this)) { return Attempt.Fail( @@ -762,11 +862,19 @@ namespace Umbraco.Core.Services var moveInfo = new List>(); var uow = UowProvider.GetUnitOfWork(); + using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow)) using (var repository = RepositoryFactory.CreateContentTypeRepository(uow)) { try { - moveInfo.AddRange(repository.Move(toMove, parentId)); + EntityContainer container = null; + if (containerId > 0) + { + container = containerRepository.Get(containerId); + if (container == null || container.ContainedObjectType != Constants.ObjectTypes.DocumentTypeGuid) + throw new DataOperationException(MoveOperationStatusType.FailedParentNotFound); + } + moveInfo.AddRange(repository.Move(toMove, container)); } catch (DataOperationException ex) { diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index 4def86836a..bd505ec283 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -27,14 +27,22 @@ namespace Umbraco.Core.Services { } + #region Containers + public Attempt CreateContainer(int parentId, string name, int userId = 0) { var uow = UowProvider.GetUnitOfWork(); - using (var repo = RepositoryFactory.CreateDataTypeDefinitionRepository(uow)) + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) { try { - var container = repo.CreateContainer(parentId, name, userId); + var container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) + { + Name = name, + ParentId = parentId, + CreatorId = userId + }; + repo.AddOrUpdate(container); uow.Commit(); return Attempt.Succeed(container.Id); } @@ -46,17 +54,62 @@ namespace Umbraco.Core.Services } } - public void DeleteContainer(int containerId, int userId = 0) + public EntityContainer GetContainer(int containerId) { var uow = UowProvider.GetUnitOfWork(); - using (var repo = RepositoryFactory.CreateDataTypeDefinitionRepository(uow)) + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) { - repo.DeleteContainer(containerId); + var container = repo.Get(containerId); + return container != null && container.ContainedObjectType == Constants.ObjectTypes.DataTypeGuid + ? container + : null; + } + } + + public EntityContainer GetContainer(Guid containerId) + { + var uow = UowProvider.GetUnitOfWork(); + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) + { + var container = repo.Get(containerId); + return container != null && container.ContainedObjectType == Constants.ObjectTypes.DataTypeGuid + ? container + : null; + } + } + + public void SaveContainer(EntityContainer container, int userId = 0) + { + if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid) + throw new InvalidOperationException("Not a data type container."); + if (container.HasIdentity && container.IsPropertyDirty("ParentId")) + throw new InvalidOperationException("Cannot save a container with a modified parent, move the container instead."); + + var uow = UowProvider.GetUnitOfWork(); + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) + { + repo.AddOrUpdate(container); uow.Commit(); //TODO: Audit trail ? } } + public void DeleteContainer(int containerId, int userId = 0) + { + var uow = UowProvider.GetUnitOfWork(); + using (var repo = RepositoryFactory.CreateEntityContainerRepository(uow)) + { + var container = repo.Get(containerId); + if (container == null) return; + if (container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid) return; + repo.Delete(container); + uow.Commit(); + //TODO: Audit trail ? + } + } + + #endregion + /// /// Gets a by its Name /// @@ -199,11 +252,19 @@ namespace Umbraco.Core.Services var moveInfo = new List>(); var uow = UowProvider.GetUnitOfWork(); + using (var containerRepository = RepositoryFactory.CreateEntityContainerRepository(uow)) using (var repository = RepositoryFactory.CreateDataTypeDefinitionRepository(uow)) { try { - moveInfo.AddRange(repository.Move(toMove, parentId)); + EntityContainer container = null; + if (parentId > 0) + { + container = containerRepository.Get(parentId); + if (container == null || container.ContainedObjectType != Constants.ObjectTypes.DataTypeGuid) + throw new DataOperationException(MoveOperationStatusType.FailedParentNotFound); + } + moveInfo.AddRange(repository.Move(toMove, container)); } catch (DataOperationException ex) { diff --git a/src/Umbraco.Core/Services/IContentTypeService.cs b/src/Umbraco.Core/Services/IContentTypeService.cs index 6be2174fdf..9e59308a39 100644 --- a/src/Umbraco.Core/Services/IContentTypeService.cs +++ b/src/Umbraco.Core/Services/IContentTypeService.cs @@ -20,8 +20,14 @@ namespace Umbraco.Core.Services Attempt CreateContentTypeContainer(int parentId, string name, int userId = 0); Attempt CreateMediaTypeContainer(int parentId, string name, int userId = 0); + void SaveContentTypeContainer(EntityContainer container, int userId = 0); + void SaveMediaTypeContainer(EntityContainer container, int userId = 0); + EntityContainer GetContentTypeContainer(int containerId); + EntityContainer GetContentTypeContainer(Guid containerId); + EntityContainer GetMediaTypeContainer(int containerId); + EntityContainer GetMediaTypeContainer(Guid containerId); void DeleteMediaTypeContainer(int folderId, int userId = 0); - void DeleteContentTypeContainer(int folderId, int userId = 0); + void DeleteContentTypeContainer(int containerId, int userId = 0); /// /// Gets all property type aliases. @@ -263,7 +269,7 @@ namespace Umbraco.Core.Services /// True if the media type has any children otherwise False bool MediaTypeHasChildren(Guid id); - Attempt> MoveMediaType(IMediaType toMove, int parentId); - Attempt> MoveContentType(IContentType toMove, int parentId); + Attempt> MoveMediaType(IMediaType toMove, int containerId); + Attempt> MoveContentType(IContentType toMove, int containerId); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs index 6a9137030b..ce9e4a3901 100644 --- a/src/Umbraco.Core/Services/IDataTypeService.cs +++ b/src/Umbraco.Core/Services/IDataTypeService.cs @@ -11,6 +11,9 @@ namespace Umbraco.Core.Services public interface IDataTypeService : IService { Attempt CreateContainer(int parentId, string name, int userId = 0); + void SaveContainer(EntityContainer container, int userId = 0); + EntityContainer GetContainer(int containerId); + EntityContainer GetContainer(Guid containerId); void DeleteContainer(int containerId, int userId = 0); /// diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs index d5870810f8..35a25a0084 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -56,6 +56,17 @@ namespace Umbraco.Tests.Persistence.Repositories return contentTypeRepository; } + private MediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork unitOfWork) + { + var contentTypeRepository = new MediaTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); + return contentTypeRepository; + } + + private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork) + { + return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); + } + //TODO Add test to verify SetDefaultTemplates updates both AllowedTemplates and DefaultTemplate(id). @@ -100,12 +111,15 @@ namespace Umbraco.Tests.Persistence.Repositories { var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - var container = repository.CreateContainer(-1, "blah", 0); + var container1 = new EntityContainer(Constants.ObjectTypes.DocumentTypeGuid) { Name = "blah1" }; + containerRepository.AddOrUpdate(container1); unitOfWork.Commit(); - var container2 = repository.CreateContainer(container.Id, "blah2", 0); + var container2 = new EntityContainer(Constants.ObjectTypes.DocumentTypeGuid) { Name = "blah2", ParentId = container1.Id }; + containerRepository.AddOrUpdate(container2); unitOfWork.Commit(); var contentType = (IContentType) MockedContentTypes.CreateBasicContentType("asdfasdf"); @@ -122,7 +136,7 @@ namespace Umbraco.Tests.Persistence.Repositories repository.AddOrUpdate(contentType2); unitOfWork.Commit(); - var result = repository.Move(contentType, container.Id).ToArray(); + var result = repository.Move(contentType, container1).ToArray(); unitOfWork.Commit(); Assert.AreEqual(2, result.Count()); @@ -131,7 +145,7 @@ namespace Umbraco.Tests.Persistence.Repositories contentType = repository.Get(contentType.Id); contentType2 = repository.Get(contentType2.Id); - Assert.AreEqual(container.Id, contentType.ParentId); + Assert.AreEqual(container1.Id, contentType.ParentId); Assert.AreNotEqual(result.Single(x => x.Entity.Id == contentType.Id).OriginalPath, contentType.Path); Assert.AreNotEqual(result.Single(x => x.Entity.Id == contentType2.Id).OriginalPath, contentType2.Path); } @@ -144,16 +158,16 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DocumentTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); Assert.That(container.Id, Is.GreaterThan(0)); } - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.DocumentTypeContainer), new Guid(Constants.ObjectTypes.DocumentType))) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - var found = entityRepo.Get(container.Id); + var found = containerRepository.Get(container.Id); Assert.IsNotNull(found); } } @@ -164,23 +178,22 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DocumentTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); } - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { // Act - repository.DeleteContainer(container.Id); + containerRepository.Delete(container); unitOfWork.Commit(); - - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.DocumentTypeContainer), new Guid(Constants.ObjectTypes.DocumentType))) - { - var found = entityRepo.Get(container.Id); - Assert.IsNull(found); - } + } + using (var containerRepository = CreateContainerRepository(unitOfWork)) + { + var found = containerRepository.Get(container.Id); + Assert.IsNull(found); } } @@ -189,10 +202,11 @@ namespace Umbraco.Tests.Persistence.Repositories { var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - EntityContainer container; + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + var container = new EntityContainer(Constants.ObjectTypes.MediaTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); var contentType = MockedContentTypes.CreateSimpleContentType("test", "Test", propertyGroupName: "testGroup"); @@ -210,29 +224,28 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - IContentType contentType; - using (var repository = CreateRepository(unitOfWork)) + IMediaType contentType; + using (var containerRepository = CreateContainerRepository(unitOfWork)) + using (var repository = CreateMediaTypeRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.MediaTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); - contentType = MockedContentTypes.CreateSimpleContentType("test", "Test", propertyGroupName: "testGroup"); + contentType = MockedContentTypes.CreateSimpleMediaType("test", "Test", propertyGroupName: "testGroup"); contentType.ParentId = container.Id; repository.AddOrUpdate(contentType); unitOfWork.Commit(); } - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) + using (var repository = CreateMediaTypeRepository(unitOfWork)) { // Act - repository.DeleteContainer(container.Id); + containerRepository.Delete(container); unitOfWork.Commit(); - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.DocumentTypeContainer), new Guid(Constants.ObjectTypes.DocumentType))) - { - var found = entityRepo.Get(container.Id); - Assert.IsNull(found); - } + var found = containerRepository.Get(container.Id); + Assert.IsNull(found); contentType = repository.Get(contentType.Id); Assert.IsNotNull(contentType); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs index 850a25fd32..aa0b8a8ffe 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DataTypeDefinitionRepositoryTest.cs @@ -42,6 +42,11 @@ namespace Umbraco.Tests.Persistence.Repositories return dataTypeDefinitionRepository; } + private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork) + { + return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); + } + [TestCase("UmbracoPreVal87-21,3,48", 3, true)] [TestCase("UmbracoPreVal87-21,33,48", 3, false)] [TestCase("UmbracoPreVal87-21,33,48", 33, true)] @@ -64,12 +69,15 @@ namespace Umbraco.Tests.Persistence.Repositories { var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - var container = repository.CreateContainer(-1, "blah", 0); + var container1 = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah1" }; + containerRepository.AddOrUpdate(container1); unitOfWork.Commit(); - var container2 = repository.CreateContainer(container.Id, "blah2", 0); + var container2 = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah2", ParentId = container1.Id }; + containerRepository.AddOrUpdate(container2); unitOfWork.Commit(); var dataType = (IDataTypeDefinition) new DataTypeDefinition(container2.Id, Constants.PropertyEditors.RadioButtonListAlias) @@ -87,7 +95,7 @@ namespace Umbraco.Tests.Persistence.Repositories repository.AddOrUpdate(dataType2); unitOfWork.Commit(); - var result = repository.Move(dataType, container.Id).ToArray(); + var result = repository.Move(dataType, container1).ToArray(); unitOfWork.Commit(); Assert.AreEqual(2, result.Count()); @@ -96,7 +104,7 @@ namespace Umbraco.Tests.Persistence.Repositories dataType = repository.Get(dataType.Id); dataType2 = repository.Get(dataType2.Id); - Assert.AreEqual(container.Id, dataType.ParentId); + Assert.AreEqual(container1.Id, dataType.ParentId); Assert.AreNotEqual(result.Single(x => x.Entity.Id == dataType.Id).OriginalPath, dataType.Path); Assert.AreNotEqual(result.Single(x => x.Entity.Id == dataType2.Id).OriginalPath, dataType2.Path); } @@ -109,16 +117,16 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); Assert.That(container.Id, Is.GreaterThan(0)); } - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.DataTypeContainer), new Guid(Constants.ObjectTypes.DataType))) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - var found = entityRepo.Get(container.Id); + var found = containerRepository.Get(container.Id); Assert.IsNotNull(found); } } @@ -129,23 +137,22 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); } - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { // Act - repository.DeleteContainer(container.Id); + containerRepository.Delete(container); unitOfWork.Commit(); - - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.DataTypeContainer), new Guid(Constants.ObjectTypes.DataType))) - { - var found = entityRepo.Get(container.Id); - Assert.IsNull(found); - } + } + using (var containerRepository = CreateContainerRepository(unitOfWork)) + { + var found = containerRepository.Get(container.Id); + Assert.IsNull(found); } } @@ -154,10 +161,11 @@ namespace Umbraco.Tests.Persistence.Repositories { var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - EntityContainer container; + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + var container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); var dataTypeDefinition = new DataTypeDefinition(container.Id, Constants.PropertyEditors.RadioButtonListAlias) { Name = "test" }; @@ -175,27 +183,26 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; IDataTypeDefinition dataType; + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); dataType = new DataTypeDefinition(container.Id, Constants.PropertyEditors.RadioButtonListAlias) { Name = "test" }; repository.AddOrUpdate(dataType); unitOfWork.Commit(); } + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { // Act - repository.DeleteContainer(container.Id); + containerRepository.Delete(container); unitOfWork.Commit(); - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.DataTypeContainer), new Guid(Constants.ObjectTypes.DataType))) - { - var found = entityRepo.Get(container.Id); - Assert.IsNull(found); - } + var found = containerRepository.Get(container.Id); + Assert.IsNull(found); dataType = repository.Get(dataType.Id); Assert.IsNotNull(dataType); diff --git a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs index 82a6578ebb..55d4c92722 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MediaTypeRepositoryTest.cs @@ -31,17 +31,25 @@ namespace Umbraco.Tests.Persistence.Repositories return new MediaTypeRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); } + private EntityContainerRepository CreateContainerRepository(IDatabaseUnitOfWork unitOfWork) + { + return new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax); + } + [Test] public void Can_Move() { var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - var container = repository.CreateContainer(-1, "blah", 0); + var container1 = new EntityContainer(Constants.ObjectTypes.MediaTypeGuid) { Name = "blah1" }; + containerRepository.AddOrUpdate(container1); unitOfWork.Commit(); - var container2 = repository.CreateContainer(container.Id, "blah2", 0); + var container2 = new EntityContainer(Constants.ObjectTypes.MediaTypeGuid) { Name = "blah2", ParentId = container1.Id }; + containerRepository.AddOrUpdate(container2); unitOfWork.Commit(); var contentType = (IMediaType)MockedContentTypes.CreateVideoMediaType(); @@ -58,7 +66,7 @@ namespace Umbraco.Tests.Persistence.Repositories repository.AddOrUpdate(contentType2); unitOfWork.Commit(); - var result = repository.Move(contentType, container.Id).ToArray(); + var result = repository.Move(contentType, container1).ToArray(); unitOfWork.Commit(); Assert.AreEqual(2, result.Count()); @@ -67,7 +75,7 @@ namespace Umbraco.Tests.Persistence.Repositories contentType = repository.Get(contentType.Id); contentType2 = repository.Get(contentType2.Id); - Assert.AreEqual(container.Id, contentType.ParentId); + Assert.AreEqual(container1.Id, contentType.ParentId); Assert.AreNotEqual(result.Single(x => x.Entity.Id == contentType.Id).OriginalPath, contentType.Path); Assert.AreNotEqual(result.Single(x => x.Entity.Id == contentType2.Id).OriginalPath, contentType2.Path); } @@ -80,16 +88,16 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); Assert.That(container.Id, Is.GreaterThan(0)); } - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.MediaTypeContainer), new Guid(Constants.ObjectTypes.MediaType))) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - var found = entityRepo.Get(container.Id); + var found = containerRepository.Get(container.Id); Assert.IsNotNull(found); } } @@ -100,23 +108,22 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); } - using (var repository = CreateRepository(unitOfWork)) + using (var containerRepository = CreateContainerRepository(unitOfWork)) { // Act - repository.DeleteContainer(container.Id); + containerRepository.Delete(container); unitOfWork.Commit(); - - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.MediaTypeContainer), new Guid(Constants.ObjectTypes.MediaType))) - { - var found = entityRepo.Get(container.Id); - Assert.IsNull(found); - } + } + using (var containerRepository = CreateContainerRepository(unitOfWork)) + { + var found = containerRepository.Get(container.Id); + Assert.IsNull(found); } } @@ -125,10 +132,11 @@ namespace Umbraco.Tests.Persistence.Repositories { var provider = new PetaPocoUnitOfWorkProvider(Logger); var unitOfWork = provider.GetUnitOfWork(); - EntityContainer container; + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + var container = new EntityContainer(Constants.ObjectTypes.DataTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); var contentType = MockedContentTypes.CreateVideoMediaType(); @@ -147,9 +155,11 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); EntityContainer container; IMediaType contentType; + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { - container = repository.CreateContainer(-1, "blah", 0); + container = new EntityContainer(Constants.ObjectTypes.MediaTypeGuid) { Name = "blah" }; + containerRepository.AddOrUpdate(container); unitOfWork.Commit(); contentType = MockedContentTypes.CreateVideoMediaType(); @@ -157,18 +167,15 @@ namespace Umbraco.Tests.Persistence.Repositories repository.AddOrUpdate(contentType); unitOfWork.Commit(); } + using (var containerRepository = CreateContainerRepository(unitOfWork)) using (var repository = CreateRepository(unitOfWork)) { // Act - repository.DeleteContainer(container.Id); + containerRepository.Delete(container); unitOfWork.Commit(); - using (var entityRepo = new EntityContainerRepository(unitOfWork, CacheHelper.CreateDisabledCacheHelper(), Mock.Of(), SqlSyntax, - new Guid(Constants.ObjectTypes.MediaTypeContainer), new Guid(Constants.ObjectTypes.MediaType))) - { - var found = entityRepo.Get(container.Id); - Assert.IsNull(found); - } + var found = containerRepository.Get(container.Id); + Assert.IsNull(found); contentType = repository.Get(contentType.Id); Assert.IsNotNull(contentType); diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index 09839bf251..3eb0df882a 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -191,8 +191,35 @@ namespace Umbraco.Tests.TestHelpers.Entities contentType.SetDefaultTemplate(new Template("Textpage", "textpage")); return contentType; - } + } + public static MediaType CreateSimpleMediaType(string alias, string name, IMediaType parent = null, bool randomizeAliases = false, string propertyGroupName = "Content") + { + var contentType = parent == null ? new MediaType(-1) : new MediaType(parent, alias); + + contentType.Alias = alias; + contentType.Name = name; + contentType.Description = "ContentType used for simple text pages"; + contentType.Icon = ".sprTreeDoc3"; + contentType.Thumbnail = "doc2.png"; + contentType.SortOrder = 1; + contentType.CreatorId = 0; + contentType.Trashed = false; + + var contentCollection = new PropertyTypeCollection(); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = RandomAlias("title", randomizeAliases), Name = "Title", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TinyMCEAlias, DataTypeDatabaseType.Ntext) { Alias = RandomAlias("bodyText", randomizeAliases), Name = "Body Text", Description = "", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -87 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = RandomAlias("author", randomizeAliases), Name = "Author", Description = "Name of the author", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88 }); + + var pg = new PropertyGroup(contentCollection) { Name = propertyGroupName, SortOrder = 1 }; + contentType.PropertyGroups.Add(pg); + + //ensure that nothing is marked as dirty + contentType.ResetDirtyProperties(false); + + return contentType; + } + public static ContentType CreateSimpleContentType(string alias, string name, bool mandatory) { var contentType = new ContentType(-1)