From 4e2bcee35bc6bfeea67d80cd454df6c01a7428c8 Mon Sep 17 00:00:00 2001 From: sitereactor Date: Wed, 31 Oct 2012 15:15:02 -0100 Subject: [PATCH] Adding more tests to cover the ContentService and refactoring. --- .../Persistence/Factories/PropertyFactory.cs | 8 +- .../Persistence/PetaPocoExtensions.cs | 2 + .../Persistence/Querying/ExpressionHelper.cs | 3 + .../Repositories/ContentRepository.cs | 8 +- src/Umbraco.Tests/App.config | 14 +- .../Services/ContentServiceTests.cs | 254 ++++++++++++++++-- .../TestHelpers/Entities/MockedContent.cs | 4 +- .../Entities/MockedContentTypes.cs | 25 ++ .../Publishing/PublishingStrategy.cs | 4 +- src/Umbraco.Web/Services/ContentService.cs | 45 +++- 10 files changed, 322 insertions(+), 45 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs index 1971bf1d56..f846db0f86 100644 --- a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs @@ -55,19 +55,19 @@ namespace Umbraco.Core.Persistence.Factories var result = service.ToStream(property.Value); dto.Text = result.ResultStream.ToJsonString(); }*/ - if (property.DataTypeDatabaseType == DataTypeDatabaseType.Integer) + if (property.DataTypeDatabaseType == DataTypeDatabaseType.Integer && property.Value != null) { dto.Integer = int.Parse(property.Value.ToString()); } - else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Date) + else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Date && property.Value != null) { dto.Date = DateTime.Parse(property.Value.ToString()); } - else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Ntext) + else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Ntext && property.Value != null) { dto.Text = property.Value.ToString(); } - else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Nvarchar) + else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Nvarchar && property.Value != null) { dto.VarChar = property.Value.ToString(); } diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index 880f653a32..f43b995e1d 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -35,6 +35,7 @@ namespace Umbraco.Core.Persistence var foreignSql = SyntaxConfig.SqlSyntaxProvider.ToCreateForeignKeyStatements(tableDefinition); var indexSql = SyntaxConfig.SqlSyntaxProvider.ToCreateIndexStatements(tableDefinition); + /* #if DEBUG Console.WriteLine(createSql); Console.WriteLine(createPrimaryKeySql); @@ -47,6 +48,7 @@ namespace Umbraco.Core.Persistence Console.WriteLine(sql); } #endif + */ var tableExist = db.TableExist(tableName); if (overwrite && tableExist) diff --git a/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs b/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs index e1dfa3c9e7..57550654ff 100644 --- a/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs +++ b/src/Umbraco.Core/Persistence/Querying/ExpressionHelper.cs @@ -479,6 +479,9 @@ namespace Umbraco.Core.Persistence.Querying if (fieldType == typeof(decimal)) return ((decimal)value).ToString(CultureInfo.InvariantCulture); + if(fieldType == typeof(DateTime)) + return "'" + EscapeParam(((DateTime)value).ToString(CultureInfo.InvariantCulture)) + "'"; + return ShouldQuoteValue(fieldType) ? "'" + EscapeParam(value) + "'" : value.ToString(); diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 12291b3425..7d75308e66 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -83,7 +83,7 @@ namespace Umbraco.Core.Persistence.Repositories //NOTE: This doesn't allow properties to be part of the query var dtos = Database.Fetch(sql); - foreach (var dto in dtos) + foreach (var dto in dtos.DistinctBy(x => x.NodeId)) { yield return Get(dto.NodeId); } @@ -259,7 +259,8 @@ namespace Umbraco.Core.Persistence.Repositories public IEnumerable GetAllVersions(int id) { var contentSql = GetBaseQuery(false); - contentSql.Append(GetBaseWhereClause(id)); + //contentSql.Append(GetBaseWhereClause(id)); + contentSql.Where("[umbracoNode].[id] = @Id", new { Id = id }); contentSql.OrderBy("[cmsContentVersion].[VersionDate] DESC"); var documentDtos = Database.Fetch(contentSql); @@ -272,7 +273,8 @@ namespace Umbraco.Core.Persistence.Repositories public IContent GetByVersion(int id, Guid versionId) { var contentSql = GetBaseQuery(false); - contentSql.Append(GetBaseWhereClause(id)); + //contentSql.Append(GetBaseWhereClause(id)); + contentSql.Where("[umbracoNode].[id] = @Id", new { Id = id }); contentSql.Where("[cmsContentVersion].[VersionId] = @VersionId", new { VersionId = versionId }); contentSql.OrderBy("[cmsContentVersion].[VersionDate] DESC"); diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index d2c4862ae2..5e5571f686 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -57,14 +57,14 @@ - - + + - - - - - + + + + + diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 40410b5fc5..28ba07dde6 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -8,6 +8,11 @@ using Umbraco.Tests.TestHelpers.Entities; namespace Umbraco.Tests.Services { + /// + /// Tests covering all methods in the ContentService class. + /// This is more of an integration test as it involves multiple layers + /// as well as configuration. + /// [TestFixture] public class ContentServiceTests : BaseDatabaseFactoryTest { @@ -25,7 +30,7 @@ namespace Umbraco.Tests.Services var contentService = ServiceContext.ContentService; // Act - IContent content = contentService.CreateContent(-1, "umbTextpage"); + var content = contentService.CreateContent(-1, "umbTextpage"); // Assert Assert.That(content, Is.Not.Null); @@ -86,59 +91,270 @@ namespace Umbraco.Tests.Services Assert.That(contents.Count(), Is.GreaterThanOrEqualTo(2)); } + [Test] public void Can_Get_All_Versions_Of_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var subpage2 = contentService.GetById(1048); + subpage2.Name = "Text Page 2 Updated"; + subpage2.SetValue("author", "Jane Doe"); + contentService.Save(subpage2, 0); + // Act + var versions = contentService.GetVersions(1048); + + // Assert + Assert.That(versions.Any(), Is.True); + Assert.That(versions.Count(), Is.GreaterThanOrEqualTo(2)); + } + + [Test] public void Can_Get_Root_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + // Act + var contents = contentService.GetRootContent(); + + // Assert + Assert.That(contents, Is.Not.Null); + Assert.That(contents.Any(), Is.True); + Assert.That(contents.Count(), Is.EqualTo(1)); + } + + [Test] public void Can_Get_Content_For_Expiration() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + // Act + var contents = contentService.GetContentForExpiration(); + + // Assert + Assert.That(DateTime.UtcNow.AddMinutes(-5) <= DateTime.UtcNow); + Assert.That(contents, Is.Not.Null); + Assert.That(contents.Any(), Is.True); + Assert.That(contents.Count(), Is.EqualTo(1)); + } + + [Test] public void Can_Get_Content_For_Release() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + // Act + var contents = contentService.GetContentForRelease(); + + // Assert + Assert.That(DateTime.UtcNow.AddMinutes(-5) <= DateTime.UtcNow); + Assert.That(contents, Is.Not.Null); + Assert.That(contents.Any(), Is.True); + Assert.That(contents.Count(), Is.EqualTo(1)); + } + + [Test] public void Can_Get_Content_In_RecycleBin() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + // Act + var contents = contentService.GetContentInRecycleBin(); + + // Assert + Assert.That(contents, Is.Not.Null); + Assert.That(contents.Any(), Is.True); + Assert.That(contents.Count(), Is.EqualTo(1)); + } + + [Test] public void Can_RePublish_All_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var contentTypeService = ServiceContext.ContentTypeService; + var contentType = contentTypeService.GetContentType("umbTextpage"); + + // Act + contentService.RePublishAll(0); + var contents = contentService.GetContentOfContentType(contentType.Id); + + // Assert + Assert.That(contents.First(x => x.Id == 1046).Published, Is.True);//No restrictions, so should be published + Assert.That(contents.First(x => x.Id == 1047).Published, Is.True);//Released 5 mins ago, so should be published + Assert.That(contents.First(x => x.Id == 1048).Published, Is.False);//Expired 5 mins ago, so shouldn't be published + Assert.That(contents.First(x => x.Id == 1049).Published, Is.False);//Trashed content, so shouldn't be published + } public void Can_Publish_Content() { } + public void Can_Publish_Only_Valid_Content() + { } + public void Can_Publish_Content_Children() { } public void Can_Save_And_Publish_Content() { } + [Test] public void Can_Save_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var content = contentService.CreateContent(-1, "umbTextpage"); + content.Name = "Home US"; + content.SetValue("author", "Barack Obama"); + // Act + contentService.Save(content, 0); + + // Assert + Assert.That(content.HasIdentity, Is.True); + } + + [Test] public void Can_Bulk_Save_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var contentTypeService = ServiceContext.ContentTypeService; + var contentType = contentTypeService.GetContentType("umbTextpage"); + Content subpage = MockedContent.CreateTextpageContent(contentType, "Text Subpage 1", 1047); + Content subpage2 = MockedContent.CreateTextpageContent(contentType, "Text Subpage 2", 1047); + var list = new List {subpage, subpage2}; + + // Act + contentService.Save(list, 0); + + // Assert + Assert.That(list.Any(x => !x.HasIdentity), Is.False); + } + + [Test] public void Can_Delete_Content_Of_Specific_ContentType() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var contentTypeService = ServiceContext.ContentTypeService; + var contentType = contentTypeService.GetContentType("umbTextpage"); + // Act + contentService.DeleteContentOfType(contentType.Id); + var rootContent = contentService.GetRootContent(); + var contents = contentService.GetContentOfContentType(contentType.Id); + + // Assert + Assert.That(rootContent.Any(), Is.False); + Assert.That(contents.Any(x => !x.Trashed), Is.False); + } + + [Test] public void Can_Delete_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var content = contentService.GetById(1049); + // Act + contentService.Delete(content, 0); + var deleted = contentService.GetById(1049); + + // Assert + Assert.That(deleted, Is.Null); + } + + [Test] public void Can_Move_Content_To_RecycleBin() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var content = contentService.GetById(1048); + // Act + contentService.MoveToRecycleBin(content, 0); + + // Assert + Assert.That(content.ParentId, Is.EqualTo(-20)); + Assert.That(content.Trashed, Is.True); + } + + [Test] + public void Can_Empty_RecycleBin() + { + // Arrange + var contentService = ServiceContext.ContentService; + + // Act + contentService.EmptyRecycleBin(); + var contents = contentService.GetContentInRecycleBin(); + + // Assert + Assert.That(contents.Any(), Is.False); + } + + [Test] public void Can_Move_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var content = contentService.GetById(1049); + // Act - moving out of recycle bin + contentService.Move(content, 1046, 0); + + // Assert + Assert.That(content.ParentId, Is.EqualTo(1046)); + Assert.That(content.Trashed, Is.False); + Assert.That(content.Published, Is.False); + } + + [Test] public void Can_Copy_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var content = contentService.GetById(1048); + + // Act + var copy = contentService.Copy(content, content.ParentId, 0); + + // Assert + Assert.That(copy, Is.Not.Null); + Assert.That(copy.Id, Is.Not.EqualTo(content.Id)); + Assert.AreNotSame(content, copy); + Assert.AreNotEqual(content.Name, copy.Name); + } public void Can_Send_To_Publication() { } + [Test] public void Can_Rollback_Version_On_Content() - { } + { + // Arrange + var contentService = ServiceContext.ContentService; + var subpage2 = contentService.GetById(1048); + var version = subpage2.Version; + subpage2.Name = "Text Page 2 Updated"; + subpage2.SetValue("author", "Jane Doe"); + contentService.Save(subpage2, 0); + + // Act + var rollback = contentService.Rollback(1048, version, 0); + + // Assert + Assert.That(rollback, Is.Not.Null); + Assert.AreNotEqual(rollback.Version, version); + Assert.That(rollback.GetValue("author"), Is.Not.EqualTo("Jane Doe")); + Assert.AreEqual(subpage2.Name, rollback.Name); + } public void CreateTestData() { @@ -154,11 +370,19 @@ namespace Umbraco.Tests.Services //Create and Save Content "Text Page 1" based on "umbTextpage" -> 1047 Content subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", textpage.Id); + subpage.ReleaseDate = DateTime.UtcNow.AddMinutes(-5); ServiceContext.ContentService.Save(subpage, 0); //Create and Save Content "Text Page 1" based on "umbTextpage" -> 1048 Content subpage2 = MockedContent.CreateTextpageContent(contentType, "Text Page 2", textpage.Id); + subpage2.ExpireDate = DateTime.UtcNow.AddMinutes(-5); + subpage2.ChangePublishedState(true); ServiceContext.ContentService.Save(subpage2, 0); + + //Create and Save Content "Text Page Deleted" based on "umbTextpage" -> 1049 + Content trashed = MockedContent.CreateTextpageContent(contentType, "Text Page Deleted", -20); + trashed.Trashed = true; + ServiceContext.ContentService.Save(trashed, 0); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs index 01ed04b128..e59b010f9c 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContent.cs @@ -4,7 +4,7 @@ namespace Umbraco.Tests.TestHelpers.Entities { public class MockedContent { - public static Content CreateTextpageContent(ContentType contentType) + public static Content CreateTextpageContent(IContentType contentType) { var content = new Content(-1, contentType) {Name = "Home", Language = "en-US", Level = 1, ParentId = -1, SortOrder = 1, Template = "~/masterpages/umbTextPage.master", UserId = 0}; object obj = @@ -20,7 +20,7 @@ namespace Umbraco.Tests.TestHelpers.Entities return content; } - public static Content CreateTextpageContent(ContentType contentType, string name, int parentId) + public static Content CreateTextpageContent(IContentType contentType, string name, int parentId) { var content = new Content(parentId, contentType) { Name = name, Language = "en-US", ParentId = parentId, Template = "~/masterpages/umbTextPage.master", UserId = 0 }; object obj = diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index e36deae013..e5593067d2 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -108,6 +108,31 @@ namespace Umbraco.Tests.TestHelpers.Entities return contentType; } + public static ContentType CreateSimpleContentType(string alias, string name, bool mandatory) + { + var contentType = new ContentType(-1) + { + Alias = alias, + Name = name, + Description = "ContentType used for simple text pages", + Icon = ".sprTreeDoc3", + Thumbnail = "doc2.png", + SortOrder = 1, + UserId = 0, + DefaultTemplate = "~/masterpages/umbSimplePage.master", + Trashed = false + }; + + var contentCollection = new PropertyTypeCollection(); + contentCollection.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "title", Name = "Title", Description = "", HelpText = "", Mandatory = mandatory, SortOrder = 1, DataTypeId = -88 }); + contentCollection.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "bodyText", Name = "Body Text", Description = "", HelpText = "", Mandatory = mandatory, SortOrder = 2, DataTypeId = -87 }); + contentCollection.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "author", Name = "Author", Description = "Name of the author", HelpText = "", Mandatory = mandatory, SortOrder = 3, DataTypeId = -88 }); + + contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); + + return contentType; + } + public static ContentType CreateSimpleContentType(string alias, string name, PropertyTypeCollection collection) { var contentType = new ContentType(-1) diff --git a/src/Umbraco.Web/Publishing/PublishingStrategy.cs b/src/Umbraco.Web/Publishing/PublishingStrategy.cs index b4184af061..f78884619b 100644 --- a/src/Umbraco.Web/Publishing/PublishingStrategy.cs +++ b/src/Umbraco.Web/Publishing/PublishingStrategy.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -59,7 +60,8 @@ namespace Umbraco.Web.Publishing if (e.Cancel) return false; - foreach (var content in children) + //Only update content thats not already been published + foreach (var content in children.Where(x => x.Published == false)) { FireBeforePublish(content, e); diff --git a/src/Umbraco.Web/Services/ContentService.cs b/src/Umbraco.Web/Services/ContentService.cs index 6b63fa5624..0aa5b0f2a3 100644 --- a/src/Umbraco.Web/Services/ContentService.cs +++ b/src/Umbraco.Web/Services/ContentService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Models.EntityBase; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Repositories; @@ -144,28 +145,28 @@ namespace Umbraco.Web.Services } /// - /// Gets a collection of objects, which has an expiration date greater then today + /// Gets a collection of objects, which has an expiration date less than or equal to today. /// /// An Enumerable list of objects public IEnumerable GetContentForExpiration() { var repository = RepositoryResolver.ResolveByType(_unitOfWork); - var query = Query.Builder.Where(x => x.Published == true && x.ExpireDate != null && x.ExpireDate.Value <= DateTime.Now); + var query = Query.Builder.Where(x => x.Published == true && x.ExpireDate <= DateTime.UtcNow); var contents = repository.GetByQuery(query); return contents; } /// - /// Gets a collection of objects, which has a release date greater then today + /// Gets a collection of objects, which has a release date less than or equal to today. /// /// An Enumerable list of objects public IEnumerable GetContentForRelease() { var repository = RepositoryResolver.ResolveByType(_unitOfWork); - var query = Query.Builder.Where(x => x.Published == true && x.ReleaseDate != null && x.ReleaseDate.Value <= DateTime.Now); + var query = Query.Builder.Where(x => x.Published == false && x.ReleaseDate <= DateTime.UtcNow); var contents = repository.GetByQuery(query); return contents; @@ -204,6 +205,7 @@ namespace Umbraco.Web.Services { if(content.IsValid()) { + list.Add(content); list.AddRange(GetChildrenDeep(content.Id)); } } @@ -212,7 +214,8 @@ namespace Umbraco.Web.Services var published = _publishingStrategy.PublishWithChildren(list, userId); if (published) { - foreach (var item in list) + //Only loop through content where the Published property has been updated + foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published"))) { repository.AddOrUpdate(item); } @@ -220,7 +223,7 @@ namespace Umbraco.Web.Services _unitOfWork.Commit(); //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class. - global::umbraco.library.RefreshContent(); + //global::umbraco.library.RefreshContent(); } return published; @@ -276,7 +279,8 @@ namespace Umbraco.Web.Services var published = _publishingStrategy.PublishWithChildren(list, userId); if (published) { - foreach (var item in list) + //Only loop through content where the Published property has been updated + foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published"))) { repository.AddOrUpdate(item); } @@ -285,7 +289,7 @@ namespace Umbraco.Web.Services //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class. //TODO Need to investigate if it will also update the cache for children of the Content object - global::umbraco.library.UpdateDocumentCache(content.Id); + //global::umbraco.library.UpdateDocumentCache(content.Id); } return published; @@ -301,6 +305,7 @@ namespace Umbraco.Web.Services { var repository = RepositoryResolver.ResolveByType(_unitOfWork); + //TODO Look for children and unpublish them if any exists var unpublished = _publishingStrategy.UnPublish(content, userId); if (unpublished) @@ -309,7 +314,7 @@ namespace Umbraco.Web.Services _unitOfWork.Commit(); //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content class. - global::umbraco.library.UnPublishSingleNode(content.Id); + //global::umbraco.library.UnPublishSingleNode(content.Id); } return unpublished; @@ -378,7 +383,7 @@ namespace Umbraco.Web.Services _unitOfWork.Commit(); //TODO Change this so we can avoid a depencency to the horrible library method / umbraco.content (singleton) class. - global::umbraco.library.UpdateDocumentCache(content.Id); + //global::umbraco.library.UpdateDocumentCache(content.Id); } return published; @@ -460,7 +465,7 @@ namespace Umbraco.Web.Services //TODO If content item has children those should also be moved to the recycle bin //TODO Unpublish deleted content + children var repository = RepositoryResolver.ResolveByType(_unitOfWork); - ((Content)content).ChangeTrashedState(true); + content.ChangeTrashedState(true); repository.AddOrUpdate(content); _unitOfWork.Commit(); } @@ -478,7 +483,17 @@ namespace Umbraco.Web.Services /// Id of the User moving the Content public void Move(IContent content, int parentId, int userId) { - content.ParentId = parentId; + //If Content is being moved away from Recycle Bin, its state should be un-trashed + if(content.Trashed && parentId != -20) + { + content.ChangeTrashedState(false, parentId); + } + else + { + content.ParentId = parentId; + } + + //If Content is published, it should be (re)published from its new location if(content.Published) { SaveAndPublish(content, userId); @@ -518,6 +533,7 @@ namespace Umbraco.Web.Services { var copy = ((Content) content).Clone(); copy.ParentId = parentId; + copy.Name = copy.Name + " (1)"; var repository = RepositoryResolver.ResolveByType(_unitOfWork); @@ -554,13 +570,16 @@ namespace Umbraco.Web.Services /// Rollback an object to a previous version. /// This will create a new version, which is a copy of all the old data. /// + /// + /// The way data is stored actually only allows us to rollback on properties + /// and not data like Name and Alias of the Content. + /// /// Id of the being rolled back /// Id of the version to rollback to /// Id of the User issueing the rollback of the Content /// The newly created object public IContent Rollback(int id, Guid versionId, int userId) { - //TODO Need to test if this actually works var repository = RepositoryResolver.ResolveByType(_unitOfWork); var content = repository.GetByVersion(id, versionId);