Skip to content

Commit

Permalink
If caching a published document, make sure you use the published Name.
Browse files Browse the repository at this point in the history
…Closes umbraco#11074.
  • Loading branch information
lordscarlet committed Oct 7, 2021
1 parent 828558a commit d309f11
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/Umbraco.Core/Strings/DefaultUrlSegmentProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ private static string GetUrlSegmentSource(IContentBase content, string culture)
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
source = (content is IContent document) && document.Edited
? document.GetPublishName(culture)
: content.GetCultureName(culture);
}
return source;
}
}
Expand Down
158 changes: 158 additions & 0 deletions src/Umbraco.Tests/PublishedContent/NuCacheRebuildTests.cs
Original file line number Diff line number Diff line change
@@ -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);

}

}
}
1 change: 1 addition & 0 deletions src/Umbraco.Tests/Umbraco.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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" />
Expand Down

0 comments on commit d309f11

Please sign in to comment.