From a1ad04e04e4680977bcc804b35322924e871ede6 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 9 Jan 2019 16:57:40 +1100 Subject: [PATCH] Refactors a bit of the BuildDtos method and adds a unit test --- .../Persistence/Factories/PropertyFactory.cs | 43 ++++++++++++----- .../Implement/DocumentRepository.cs | 6 +-- .../Repositories/Implement/MediaRepository.cs | 4 +- .../Implement/MemberRepository.cs | 4 +- .../Services/ContentServiceTests.cs | 48 +++++++++++++++++++ 5 files changed, 86 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs index c1ae68b44d..5381251557 100644 --- a/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/PropertyFactory.cs @@ -93,20 +93,36 @@ namespace Umbraco.Core.Persistence.Factories return dto; } - public static IEnumerable BuildDtos(int currentVersionId, int publishedVersionId, IEnumerable properties, - ILanguageRepository languageRepository, out bool edited, out HashSet editedCultures, IEnumerable availableCultures = null) + /// + /// Creates a collection of from a collection of + /// + /// + /// The of the entity containing the collection of + /// + /// + /// + /// The properties to map + /// + /// out parameter indicating that one or more properties have been edited + /// out parameter containing a collection of of edited cultures when the contentVariation varies by culture + /// + public static IEnumerable BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable properties, + ILanguageRepository languageRepository, out bool edited, out HashSet editedCultures) { var propertyDataDtos = new List(); edited = false; editedCultures = null; // don't allocate unless necessary + string defaultCulture = null; //don't allocate unless necessary + + var entityVariesByCulture = contentVariation.VariesByCulture(); foreach (var property in properties) { if (property.PropertyType.IsPublishing) { - var editingCultures = availableCultures?.Any() ?? property.PropertyType.VariesByCulture(); - - if (editingCultures && editedCultures == null) editedCultures = new HashSet(StringComparer.OrdinalIgnoreCase); + //create the resulting hashset if it's not created and the entity varies by culture + if (entityVariesByCulture && editedCultures == null) + editedCultures = new HashSet(StringComparer.OrdinalIgnoreCase); // publishing = deal with edit and published values foreach (var propertyValue in property.Values) @@ -127,19 +143,22 @@ namespace Umbraco.Core.Persistence.Factories var sameValues = propertyValue.PublishedValue == null ? propertyValue.EditedValue == null : propertyValue.PublishedValue.Equals(propertyValue.EditedValue); edited |= !sameValues; - if (editingCultures && // cultures can be edited, ie CultureNeutral is supported - propertyValue.Culture != null && propertyValue.Segment == null && // and value is CultureNeutral - !sameValues) // and edited and published are different + if (entityVariesByCulture // cultures can be edited, ie CultureNeutral is supported + && propertyValue.Culture != null && propertyValue.Segment == null // and value is CultureNeutral + && !sameValues) // and edited and published are different { editedCultures.Add(propertyValue.Culture); // report culture as edited } // flag culture as edited if it contains an edited invariant property - if (propertyValue.Culture == null && - availableCultures !=null && !sameValues&& - editingCultures) + if (!property.PropertyType.VariesByCulture() + && !sameValues // and edited and published are different + && entityVariesByCulture) //only when the entity is variant { - editedCultures.Add(availableCultures.FirstOrDefault()); + if (defaultCulture == null) + defaultCulture = languageRepository.GetDefaultIsoCode(); + + editedCultures.Add(defaultCulture); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index ae0a2a19e3..1f24c7c414 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -352,7 +352,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } // persist the property data - var propertyDataDtos = PropertyFactory.BuildDtos(content.VersionId, content.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures); + var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, content.PublishedVersionId, entity.Properties, LanguageRepository, out var edited, out var editedCultures); foreach (var propertyDataDto in propertyDataDtos) Database.Insert(propertyDataDto); @@ -527,8 +527,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement Database.Execute(deletePropertyDataSql); // insert property data - var propertyDataDtos = PropertyFactory.BuildDtos(content.VersionId, publishing ? content.PublishedVersionId : 0, - entity.Properties, LanguageRepository, out var edited, out var editedCultures, content.AvailableCultures); + var propertyDataDtos = PropertyFactory.BuildDtos(content.ContentType.Variations, content.VersionId, publishing ? content.PublishedVersionId : 0, + entity.Properties, LanguageRepository, out var edited, out var editedCultures); foreach (var propertyDataDto in propertyDataDtos) Database.Insert(propertyDataDto); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs index dbfdc8e980..3e665e321f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MediaRepository.cs @@ -284,7 +284,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement Database.Insert(mediaVersionDto); // persist the property data - var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); + var propertyDataDtos = PropertyFactory.BuildDtos(media.ContentType.Variations, media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); foreach (var propertyDataDto in propertyDataDtos) Database.Insert(propertyDataDto); @@ -341,7 +341,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // replace the property data var deletePropertyDataSql = SqlContext.Sql().Delete().Where(x => x.VersionId == media.VersionId); Database.Execute(deletePropertyDataSql); - var propertyDataDtos = PropertyFactory.BuildDtos(media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); + var propertyDataDtos = PropertyFactory.BuildDtos(media.ContentType.Variations, media.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); foreach (var propertyDataDto in propertyDataDtos) Database.Insert(propertyDataDto); diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs index fd79b231de..bfadebd61b 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/MemberRepository.cs @@ -310,7 +310,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement Database.Insert(dto); // persist the property data - var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); + var propertyDataDtos = PropertyFactory.BuildDtos(member.ContentType.Variations, member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); foreach (var propertyDataDto in propertyDataDtos) Database.Insert(propertyDataDto); @@ -375,7 +375,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // replace the property data var deletePropertyDataSql = SqlContext.Sql().Delete().Where(x => x.VersionId == member.VersionId); Database.Execute(deletePropertyDataSql); - var propertyDataDtos = PropertyFactory.BuildDtos(member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); + var propertyDataDtos = PropertyFactory.BuildDtos(member.ContentType.Variations, member.VersionId, 0, entity.Properties, LanguageRepository, out _, out _); foreach (var propertyDataDto in propertyDataDtos) Database.Insert(propertyDataDto); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 8fba16662c..0f48a9c99a 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -792,6 +792,54 @@ namespace Umbraco.Tests.Services } + [Test] + public void Pending_Invariant_Property_Changes_Affect_Default_Language_Edited_State() + { + // Arrange + + var langGB = new Language("en-GB") { IsDefault = true }; + var langFr = new Language("fr-FR"); + + ServiceContext.LocalizationService.Save(langFr); + ServiceContext.LocalizationService.Save(langGB); + + var contentType = MockedContentTypes.CreateMetaContentType(); + contentType.Variations = ContentVariation.Culture; + foreach(var prop in contentType.PropertyTypes) + prop.Variations = ContentVariation.Culture; + var keywordsProp = contentType.PropertyTypes.Single(x => x.Alias == "metakeywords"); + keywordsProp.Variations = ContentVariation.Nothing; // this one is invariant + + ServiceContext.ContentTypeService.Save(contentType); + + IContent content = new Content("content", -1, contentType); + content.SetCultureName("content-en", langGB.IsoCode); + content.SetCultureName("content-fr", langFr.IsoCode); + content.PublishCulture(langGB.IsoCode); + content.PublishCulture(langFr.IsoCode); + Assert.IsTrue(ServiceContext.ContentService.SavePublishing(content).Success); + + //re-get + content = ServiceContext.ContentService.GetById(content.Id); + Assert.AreEqual(PublishedState.Published, content.PublishedState); + Assert.IsTrue(content.IsCulturePublished(langGB.IsoCode)); + Assert.IsTrue(content.IsCulturePublished(langFr.IsoCode)); + Assert.IsFalse(content.IsCultureEdited(langGB.IsoCode)); + Assert.IsFalse(content.IsCultureEdited(langFr.IsoCode)); + + //update the invariant property and save a pending version + content.SetValue("metakeywords", "hello"); + ServiceContext.ContentService.Save(content); + + //re-get + content = ServiceContext.ContentService.GetById(content.Id); + Assert.AreEqual(PublishedState.Published, content.PublishedState); + Assert.IsTrue(content.IsCulturePublished(langGB.IsoCode)); + Assert.IsTrue(content.IsCulturePublished(langFr.IsoCode)); + Assert.IsTrue(content.IsCultureEdited(langGB.IsoCode)); + Assert.IsFalse(content.IsCultureEdited(langFr.IsoCode)); + } + [Test] public void Can_Publish_Content_Variation_And_Detect_Changed_Cultures() {