From 7a178be0312c4c273783d7dc7e7a8e163b6d0fd7 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 27 Jun 2019 13:29:35 +0200 Subject: [PATCH] Fix getting content AtRoot --- .../PublishedContent/NuCacheChildrenTests.cs | 87 +++++++++++++++++++ .../PublishedCache/NuCache/ContentCache.cs | 16 +++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index dd656b8019..f3a520ead1 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -264,6 +264,74 @@ namespace Umbraco.Tests.PublishedContent yield return CreateKit(12, 4, 2); } + private IEnumerable GetVariantWithDraftKits() + { + var paths = new Dictionary { { -1, "-1" } }; + + Dictionary GetCultureInfos(int id, DateTime now) + { + var en = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + var fr = new[] { 1, 3, 4, 6, 7, 9, 10, 12 }; + + var infos = new Dictionary(); + if (en.Contains(id)) + infos["en-US"] = new CultureVariation { Name = "N" + id + "-" + "en-US", Date = now, IsDraft = false }; + if (fr.Contains(id)) + infos["fr-FR"] = new CultureVariation { Name = "N" + id + "-" + "fr-FR", Date = now, IsDraft = false }; + return infos; + } + + ContentNodeKit CreateKit(int id, int parentId, int sortOrder) + { + if (!paths.TryGetValue(parentId, out var parentPath)) + throw new Exception("Unknown parent."); + + var path = paths[id] = parentPath + "," + id; + var level = path.Count(x => x == ','); + var now = DateTime.Now; + + ContentData CreateContentData(bool published) => new ContentData + { + Name = "N" + id, + Published = published, + TemplateId = 0, + VersionId = 1, + VersionDate = now, + WriterId = 0, + Properties = new Dictionary(), + CultureInfos = GetCultureInfos(id, now) + }; + + var withDraft = id%2==0; + var withPublished = !withDraft; + + return new ContentNodeKit + { + ContentTypeId = _contentTypeVariant.Id, + Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0), + DraftData = withDraft ? CreateContentData(false) : null, + PublishedData = withPublished ? CreateContentData(true) : null + }; + } + + yield return CreateKit(1, -1, 1); + yield return CreateKit(2, -1, 2); + yield return CreateKit(3, -1, 3); + + yield return CreateKit(4, 1, 1); + yield return CreateKit(5, 1, 2); + yield return CreateKit(6, 1, 3); + + yield return CreateKit(7, 2, 3); + yield return CreateKit(8, 2, 2); + yield return CreateKit(9, 2, 1); + + yield return CreateKit(10, 3, 1); + + yield return CreateKit(11, 4, 1); + yield return CreateKit(12, 4, 2); + } + [Test] public void EmptyTest() { @@ -747,6 +815,25 @@ namespace Umbraco.Tests.PublishedContent AssertDocuments(documents, "N9", "N8", "N7"); } + [Test] + public void AtRootTest() + { + Init(GetVariantWithDraftKits()); + + var snapshot = _snapshotService.CreatePublishedSnapshot(previewToken: null); + _snapshotAccessor.PublishedSnapshot = snapshot; + + _variationAccesor.VariationContext = new VariationContext("en-US"); + + // N2 is draft only + + var documents = snapshot.Content.GetAtRoot().ToArray(); + AssertDocuments(documents, "N1-en-US", /*"N2-en-US",*/ "N3-en-US"); + + documents = snapshot.Content.GetAtRoot(true).ToArray(); + AssertDocuments(documents, "N1-en-US", "N2-en-US", "N3-en-US"); + } + private void AssertDocuments(IPublishedContent[] documents, params string[] names) { Assert.AreEqual(names.Length, documents.Length); diff --git a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs index fa879b7879..84edb9113c 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/ContentCache.cs @@ -261,10 +261,22 @@ namespace Umbraco.Web.PublishedCache.NuCache if (culture == null) culture = _variationContextAccessor?.VariationContext?.Culture ?? ""; + // _snapshot.GetAtRoot() returns all ContentNode at root // both .Draft and .Published cannot be null at the same time // root is already sorted by sortOrder, and does not contain nulls - var atRoot = _snapshot.GetAtRoot().Select(n => GetNodePublishedContent(n, preview)); - return culture == "*" ? atRoot : atRoot.Where(x => x.IsInvariantOrHasCulture(culture)); + // + // GetNodePublishedContent may return null if !preview and there is no + // published model, so we need to filter these nulls out + + var atRoot = _snapshot.GetAtRoot() + .Select(n => GetNodePublishedContent(n, preview)) + .WhereNotNull(); + + // if a culture is specified, we must ensure that it is avail/published + if (culture != "*") + atRoot = atRoot.Where(x => x.IsInvariantOrHasCulture(culture)); + + return atRoot; } private static IPublishedContent GetNodePublishedContent(ContentNode node, bool preview)