diff --git a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs index ac3ac7d455..d67d69d46e 100644 --- a/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs +++ b/src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs @@ -213,22 +213,24 @@ namespace Umbraco.Tests.PublishedContent var level = path.Count(x => x == ','); var now = DateTime.Now; + var contentData = new ContentData + { + Name = "N" + id, + Published = true, + TemplateId = 0, + VersionId = 1, + VersionDate = now, + WriterId = 0, + Properties = new Dictionary(), + CultureInfos = new Dictionary() + }; + return new ContentNodeKit { ContentTypeId = _contentTypeInvariant.Id, Node = new ContentNode(id, Guid.NewGuid(), level, path, sortOrder, parentId, DateTime.Now, 0), DraftData = null, - PublishedData = new ContentData - { - Name = "N" + id, - Published = true, - TemplateId = 0, - VersionId = 1, - VersionDate = now, - WriterId = 0, - Properties = new Dictionary(), - CultureInfos = new Dictionary() - } + PublishedData = contentData }; } @@ -333,7 +335,7 @@ namespace Umbraco.Tests.PublishedContent CultureInfos = GetCultureInfos(id, now) }; - var withDraft = id%2==0; + var withDraft = id % 2 == 0; var withPublished = !withDraft; return new ContentNodeKit @@ -1063,6 +1065,88 @@ namespace Umbraco.Tests.PublishedContent AssertLinkedNode(child3.contentNode, 1, 2, -1, -1, -1); } + /// + /// This addresses issue: https://github.com/umbraco/Umbraco-CMS/issues/6698 + /// + /// + /// This test mimics if someone were to: + /// 1) Unpublish a "middle child" + /// 2) Save and publish it + /// 3) Publish it with descendants + /// 4) Repeat steps 2 and 3 + /// + /// Which has caused an exception. To replicate this test: + /// 1) RefreshBranch with kits for a branch where the top most node is unpublished + /// 2) RefreshBranch with kits for the branch where the top most node is published + /// 3) RefreshBranch with kits for the branch where the top most node is published + /// 4) RefreshBranch with kits for the branch where the top most node is published + /// 5) RefreshBranch with kits for the branch where the top most node is published + /// + [Test] + public void Refresh_Branch_With_Alternating_Publish_Flags() + { + // NOTE: these tests are not using real scopes, in which case a Scope does not control + // how the snapshots generations work. We are forcing new snapshot generations manually. + + IEnumerable GetKits() + { + var paths = new Dictionary { { -1, "-1" } }; + + //root + yield return CreateInvariantKit(1, -1, 1, paths); + + //children + yield return CreateInvariantKit(2, 1, 1, paths); + yield return CreateInvariantKit(3, 1, 2, paths); //middle child + yield return CreateInvariantKit(4, 1, 3, paths); + } + + //init with all published + Init(GetKits()); + + var snapshotService = (PublishedSnapshotService)_snapshotService; + var contentStore = snapshotService.GetContentStore(); + + var rootKit = _source.Kits[1].Clone(); + + void ChangePublishFlagOfRoot(bool published, int assertGen) + { + //This will set a flag to force creating a new Gen next time the store is locked (i.e. In Notify) + contentStore.CreateSnapshot(); + + Assert.IsFalse(contentStore.Test.NextGen); + + //Change the root publish flag + var kit = rootKit.Clone(); + kit.DraftData = published ? null : kit.PublishedData; + kit.PublishedData = published? kit.PublishedData : null; + _source.Kits[1] = kit; + + _snapshotService.Notify(new[] + { + new ContentCacheRefresher.JsonPayload(1, Guid.Empty, TreeChangeTypes.RefreshBranch) + }, out _, out _); + + Assert.AreEqual(assertGen, contentStore.Test.LiveGen); + Assert.IsTrue(contentStore.Test.NextGen); + } + + //unpublish the root + ChangePublishFlagOfRoot(false, 2); + + //publish the root + ChangePublishFlagOfRoot(true, 3); + + //publish root + descendants + ChangePublishFlagOfRoot(true, 4); + + //publish the root + ChangePublishFlagOfRoot(true, 5); + + //publish root + descendants + ChangePublishFlagOfRoot(true, 6); //TODO: This should fail, need to figure out what the diff is between this and a website + } + [Test] public void Refresh_Branch_Ensures_Linked_List() {