From ba501dbbb83b35eb77df7bd37e29a8edc743b34a Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 13 Jan 2017 10:43:34 +1100 Subject: [PATCH] U4-9371 Examine indexes inherited unpublished nodes on index rebuild part 2 --- src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + .../UmbracoContentIndexerTests.cs | 107 ++++++++++++++++++ src/UmbracoExamine/UmbracoContentIndexer.cs | 37 +++--- 3 files changed, 125 insertions(+), 20 deletions(-) create mode 100644 src/Umbraco.Tests/UmbracoExamine/UmbracoContentIndexerTests.cs diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index d90c0e6345..dbb877ee64 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -163,6 +163,7 @@ + diff --git a/src/Umbraco.Tests/UmbracoExamine/UmbracoContentIndexerTests.cs b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentIndexerTests.cs new file mode 100644 index 0000000000..3278130022 --- /dev/null +++ b/src/Umbraco.Tests/UmbracoExamine/UmbracoContentIndexerTests.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using Moq; +using NUnit.Framework; +using Umbraco.Core; +using Umbraco.Core.Models; +using UmbracoExamine; + +namespace Umbraco.Tests.UmbracoExamine +{ + [TestFixture] + public class UmbracoContentIndexerTests : ExamineBaseTest + { + [Test] + public void Get_Serialized_Content_No_Published_Content() + { + var contentSet = new List + { + Mock.Of(c => c.Id == 1 && c.Path == "-1,1" && c.Published && c.Level == 1), + Mock.Of(c => c.Id == 2 && c.Path == "-1,2" && c.Published && c.Level == 1), + Mock.Of(c => c.Id == 3 && c.Path == "-1,3" && c.Published == false && c.Level == 1), // no + Mock.Of(c => c.Id == 4 && c.Path == "-1,4" && c.Published == false && c.Level == 1), // no + + Mock.Of(c => c.Id == 5 && c.Path == "-1,1,5" && c.Published && c.Level == 2), + Mock.Of(c => c.Id == 6 && c.Path == "-1,2,6" && c.Published == false && c.Level == 2), // no + Mock.Of(c => c.Id == 7 && c.Path == "-1,3,7" && c.Published && c.Level == 2), // no + Mock.Of(c => c.Id == 8 && c.Path == "-1,4,8" && c.Published && c.Level == 2), // no + Mock.Of(c => c.Id == 9 && c.Path == "-1,4,9" && c.Published && c.Level == 2), // no + + Mock.Of(c => c.Id == 10 && c.Path == "-1,1,5,10" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 15 && c.Path == "-1,1,5,15" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 11 && c.Path == "-1,2,6,11" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 16 && c.Path == "-1,2,6,16" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 12 && c.Path == "-1,3,7,12" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 17 && c.Path == "-1,3,7,17" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 13 && c.Path == "-1,4,8,13" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 18 && c.Path == "-1,4,8,18" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 14 && c.Path == "-1,4,9,14" && c.Published && c.Level == 3), // no + Mock.Of(c => c.Id == 19 && c.Path == "-1,4,9,19" && c.Published && c.Level == 3), // no + }; + + //ensure the rest of the required values are populted + foreach (var content in contentSet) + { + var mock = Mock.Get(content); + mock.Setup(x => x.ContentType).Returns(Mock.Of(type => type.Icon == "hello")); + } + + contentSet.Sort((a, b) => Comparer.Default.Compare(a.Level, b.Level)); + + var published = new HashSet(); + + var result = UmbracoContentIndexer.GetSerializedContent(false, content => new XElement("test"), contentSet, published) + .WhereNotNull() + .ToArray(); + + Assert.AreEqual(5, result.Length); + } + + [Test] + public void Get_Serialized_Content_With_Published_Content() + { + var contentSet = new List + { + Mock.Of(c => c.Id == 1 && c.Path == "-1,1" && c.Published && c.Level == 1), + Mock.Of(c => c.Id == 2 && c.Path == "-1,2" && c.Published && c.Level == 1), + Mock.Of(c => c.Id == 3 && c.Path == "-1,3" && c.Published == false && c.Level == 1), + Mock.Of(c => c.Id == 4 && c.Path == "-1,4" && c.Published == false && c.Level == 1), + + Mock.Of(c => c.Id == 5 && c.Path == "-1,1,5" && c.Published && c.Level == 2), + Mock.Of(c => c.Id == 6 && c.Path == "-1,2,6" && c.Published == false && c.Level == 2), + Mock.Of(c => c.Id == 7 && c.Path == "-1,3,7" && c.Published && c.Level == 2), + Mock.Of(c => c.Id == 8 && c.Path == "-1,4,8" && c.Published && c.Level == 2), + Mock.Of(c => c.Id == 9 && c.Path == "-1,4,9" && c.Published && c.Level == 2), + + Mock.Of(c => c.Id == 10 && c.Path == "-1,1,5,10" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 15 && c.Path == "-1,1,5,15" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 11 && c.Path == "-1,2,6,11" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 16 && c.Path == "-1,2,6,16" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 12 && c.Path == "-1,3,7,12" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 17 && c.Path == "-1,3,7,17" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 13 && c.Path == "-1,4,8,13" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 18 && c.Path == "-1,4,8,18" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 14 && c.Path == "-1,4,9,14" && c.Published && c.Level == 3), + Mock.Of(c => c.Id == 19 && c.Path == "-1,4,9,19" && c.Published && c.Level == 3), + }; + + //ensure the rest of the required values are populted + foreach (var content in contentSet) + { + var mock = Mock.Get(content); + mock.Setup(x => x.ContentType).Returns(Mock.Of(type => type.Icon == "hello")); + } + + contentSet.Sort((a, b) => Comparer.Default.Compare(a.Level, b.Level)); + + var published = new HashSet(); + + var result = UmbracoContentIndexer.GetSerializedContent(true, content => new XElement("test"), contentSet, published) + .WhereNotNull() + .ToArray(); + + Assert.AreEqual(19, result.Length); + } + } +} \ No newline at end of file diff --git a/src/UmbracoExamine/UmbracoContentIndexer.cs b/src/UmbracoExamine/UmbracoContentIndexer.cs index efc3e4a214..ff3e4617e0 100644 --- a/src/UmbracoExamine/UmbracoContentIndexer.cs +++ b/src/UmbracoExamine/UmbracoContentIndexer.cs @@ -359,12 +359,7 @@ namespace UmbracoExamine } #endregion - #region Protected - - /// - /// This is a static query, it's parameters don't change so store statically - /// - private IQuery _publishedQuery; + #region Protected protected override void PerformIndexAll(string type) { @@ -395,11 +390,6 @@ namespace UmbracoExamine } else { - if (_publishedQuery == null) - { - _publishedQuery = Query.Builder.Where(x => x.Published == true); - } - //get all paged records but order by level ascending, we need to do this because we need to track which nodes are not published so that we can determine // which descendent nodes are implicitly not published descendants = _contentService.GetPagedDescendants(contentParentId, pageIndex, pageSize, out total, "level", Direction.Ascending, true, (string)null); @@ -415,7 +405,12 @@ namespace UmbracoExamine { content = descendants.ToArray(); } - AddNodesToIndex(GetSerializedContent(content, notPublished).WhereNotNull(), type); + + AddNodesToIndex(GetSerializedContent( + SupportUnpublishedContent, + c => _serializer.Serialize(_contentService, _dataTypeService, _userService, c), + content, notPublished).WhereNotNull(), type); + pageIndex++; } while (content.Length == pageSize); @@ -473,17 +468,22 @@ namespace UmbracoExamine } } - private IEnumerable GetSerializedContent(IEnumerable content, ISet notPublished) + internal static IEnumerable GetSerializedContent( + bool supportUnpublishdContent, + Func serializer, + IEnumerable content, + ISet notPublished) { foreach (var c in content) { - if (SupportUnpublishedContent == false) + if (supportUnpublishdContent == false) { //if we don't support published content and this is not published then track it and return null if (c.Published == false) { notPublished.Add(c.Path); yield return null; + continue; } //if we don't support published content, check if this content item exists underneath any already tracked @@ -491,14 +491,11 @@ namespace UmbracoExamine if (notPublished.Any(path => c.Path.StartsWith(string.Format("{0},", path)))) { yield return null; + continue; } - } + } - var xml = _serializer.Serialize( - _contentService, - _dataTypeService, - _userService, - c); + var xml = serializer(c); //add a custom 'icon' attribute xml.Add(new XAttribute("icon", c.ContentType.Icon));