If caching a published document, make sure you use the published Name… (#11313)

* If caching a published document, make sure you use the published Name. Closes #11074.

* Fix case of new node

Co-authored-by: Moore, Douglas S <Douglas.Moore@opm.gov>
This commit is contained in:
Doug Moore
2021-10-10 20:03:43 -04:00
committed by GitHub
parent 494bef878b
commit f7ea400e5a
3 changed files with 166 additions and 1 deletions

View File

@@ -24,7 +24,13 @@ namespace Umbraco.Core.Strings
if (content.HasProperty(Constants.Conventions.Content.UrlName))
source = (content.GetValue<string>(Constants.Conventions.Content.UrlName, culture) ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(source))
source = content.GetCultureName(culture);
{
// If the name of a node has been updated, but it has not been published, the url should use the published name, not the current node name
// If this node has never been published (GetPublishName is null), use the unpublished name
source = (content is IContent document) && document.Edited && document.GetPublishName(culture) != null
? document.GetPublishName(culture)
: content.GetCultureName(culture);
}
return source;
}
}

View File

@@ -0,0 +1,158 @@
using System.Globalization;
using System.Linq;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing.CompositionExtensions;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Services;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services.Implement;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Tests.Testing;
using Umbraco.Web.PropertyEditors;
using Current = Umbraco.Web.Composing.Current;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.PublishedCache.NuCache;
using System;
using Umbraco.Core.Cache;
using Umbraco.Web.Cache;
using Umbraco.Core.Sync;
using static Umbraco.Tests.Cache.DistributedCache.DistributedCacheTests;
using static Umbraco.Tests.Integration.ContentEventsTests;
using Umbraco.Tests.Services;
using Umbraco.Core.Persistence.Repositories.Implement;
using Umbraco.Tests.Testing.Objects.Accessors;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Configuration;
using Umbraco.Web.PublishedCache.NuCache.DataSource;
using Umbraco.Core.Strings;
namespace Umbraco.Tests.PublishedContent
{
[TestFixture]
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true, WithApplication = true)]
public class NuCacheRebuildTests: TestWithDatabaseBase
{
private IContentTypeService _contentTypeService;
private IContentType _contentType;
protected override void Initialize()
{
base.Initialize();
if (!(PublishedSnapshotService is PublishedSnapshotService))
{
var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true };
var runtime = Mock.Of<IRuntimeState>();
PublishedSnapshotService = new PublishedSnapshotService(
options,
null,
runtime,
ServiceContext,
Factory.GetInstance<IPublishedContentTypeFactory>(),
null,
new TestPublishedSnapshotAccessor(),
new TestVariationContextAccessor(),
Mock.Of<IProfilingLogger>(),
ScopeProvider,
Factory.GetInstance<IDocumentRepository>(), Factory.GetInstance<IMediaRepository>(), Factory.GetInstance<IMemberRepository>(),
DefaultCultureAccessor,
new DatabaseDataSource(new JsonContentNestedDataSerializerFactory()),
new GlobalSettings(),
Factory.GetInstance<IEntityXmlSerializer>(),
Factory.GetInstance<IPublishedModelFactory>(),
new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider() }),
new TestSyncBootStateAccessor(SyncBootState.WarmBoot),
new JsonContentNestedDataSerializerFactory()
);
}
}
public override void SetUp()
{
base.SetUp();
ContentRepositoryBase.ThrowOnWarning = true;
}
public override void TearDown()
{
ContentRepositoryBase.ThrowOnWarning = false;
base.TearDown();
}
protected override void Compose()
{
base.Compose();
Composition.RegisterUnique(factory => Mock.Of<ILocalizedTextService>());
}
[Test]
public void UnpublishedNameChanges()
{
var urlSegmentProvider = new DefaultUrlSegmentProvider();
var contentType = MockedContentTypes.CreateTextPageContentType();
ServiceContext.FileService.SaveTemplate(contentType.DefaultTemplate);
ServiceContext.ContentTypeService.Save(contentType);
var content = MockedContent.CreateTextpageContent(contentType, "hello", Constants.System.Root);
ServiceContext.ContentService.SaveAndPublish(content);
var cachedContent = ServiceContext.ContentService.GetById(content.Id);
var segment = urlSegmentProvider.GetUrlSegment(cachedContent);
// Does a new node work?
Assert.AreEqual("hello", segment);
content.Name = "goodbye";
cachedContent = ServiceContext.ContentService.GetById(content.Id);
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
// We didn't save anything, so all should still be the same
Assert.AreEqual("hello", segment);
ServiceContext.ContentService.Save(content);
cachedContent = ServiceContext.ContentService.GetById(content.Id);
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
// At this point we have saved the new name, but not published. The url should still be the previous name
Assert.AreEqual("hello", segment);
PublishedSnapshotService.Rebuild();
cachedContent = ServiceContext.ContentService.GetById(content.Id);
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
// After a rebuild, the unpublished name should still not be the url.
// This was previously incorrect, per #11074
Assert.AreEqual("hello", segment);
ServiceContext.ContentService.SaveAndPublish(content);
cachedContent = ServiceContext.ContentService.GetById(content.Id);
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
// The page has now been published, so we should see the new url segment
Assert.AreEqual("goodbye", segment);
PublishedSnapshotService.Rebuild();
cachedContent = ServiceContext.ContentService.GetById(content.Id);
segment = urlSegmentProvider.GetUrlSegment(cachedContent);
// Just double checking that things remain after a rebuild
Assert.AreEqual("goodbye", segment);
}
}
}

View File

@@ -157,6 +157,7 @@
<Compile Include="PropertyEditors\NestedContentPropertyComponentTests.cs" />
<Compile Include="PublishedContent\ContentSerializationTests.cs" />
<Compile Include="PublishedContent\NuCacheChildrenTests.cs" />
<Compile Include="PublishedContent\NuCacheRebuildTests.cs" />
<Compile Include="PublishedContent\PublishedContentLanguageVariantTests.cs" />
<Compile Include="PublishedContent\PublishedContentSnapshotTestBase.cs" />
<Compile Include="PublishedContent\SolidPublishedSnapshot.cs" />