V15: Refresh IPublishedContentTypeFactory when data types change (#17180)
* Refresh IPublishedContentTypeFactory when data types change * Add tests
This commit is contained in:
@@ -14,6 +14,7 @@ public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<Conten
|
||||
{
|
||||
private readonly IContentTypeCommonRepository _contentTypeCommonRepository;
|
||||
private readonly IPublishedModelFactory _publishedModelFactory;
|
||||
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
|
||||
private readonly IIdKeyMap _idKeyMap;
|
||||
|
||||
public ContentTypeCacheRefresher(
|
||||
@@ -23,12 +24,14 @@ public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<Conten
|
||||
IContentTypeCommonRepository contentTypeCommonRepository,
|
||||
IEventAggregator eventAggregator,
|
||||
ICacheRefresherNotificationFactory factory,
|
||||
IPublishedModelFactory publishedModelFactory)
|
||||
IPublishedModelFactory publishedModelFactory,
|
||||
IPublishedContentTypeFactory publishedContentTypeFactory)
|
||||
: base(appCaches, serializer, eventAggregator, factory)
|
||||
{
|
||||
_idKeyMap = idKeyMap;
|
||||
_contentTypeCommonRepository = contentTypeCommonRepository;
|
||||
_publishedModelFactory = publishedModelFactory;
|
||||
_publishedContentTypeFactory = publishedContentTypeFactory;
|
||||
}
|
||||
|
||||
#region Json
|
||||
@@ -114,6 +117,8 @@ public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<Conten
|
||||
// TODO: We need to clear the HybridCache of any content using the ContentType, but NOT the database cache here, and this should be done within the "WithSafeLiveFactoryReset" to ensure that the factory is locked in the meantime.
|
||||
_publishedModelFactory.WithSafeLiveFactoryReset(() => { });
|
||||
|
||||
_publishedContentTypeFactory.NotifyDataTypeChanges();
|
||||
|
||||
// now we can trigger the event
|
||||
base.Refresh(payloads);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeC
|
||||
{
|
||||
private readonly IIdKeyMap _idKeyMap;
|
||||
private readonly IPublishedModelFactory _publishedModelFactory;
|
||||
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
|
||||
|
||||
public DataTypeCacheRefresher(
|
||||
AppCaches appCaches,
|
||||
@@ -20,11 +21,13 @@ public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeC
|
||||
IIdKeyMap idKeyMap,
|
||||
IEventAggregator eventAggregator,
|
||||
ICacheRefresherNotificationFactory factory,
|
||||
IPublishedModelFactory publishedModelFactory)
|
||||
IPublishedModelFactory publishedModelFactory,
|
||||
IPublishedContentTypeFactory publishedContentTypeFactory)
|
||||
: base(appCaches, serializer, eventAggregator, factory)
|
||||
{
|
||||
_idKeyMap = idKeyMap;
|
||||
_publishedModelFactory = publishedModelFactory;
|
||||
_publishedContentTypeFactory = publishedContentTypeFactory;
|
||||
}
|
||||
|
||||
#region Json
|
||||
@@ -86,6 +89,9 @@ public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeC
|
||||
// TODO: We need to clear the HybridCache of any content using the ContentType, but NOT the database cache here, and this should be done within the "WithSafeLiveFactoryReset" to ensure that the factory is locked in the meantime.
|
||||
_publishedModelFactory.WithSafeLiveFactoryReset(() => { });
|
||||
|
||||
var changedIds = payloads.Select(x => x.Id).ToArray();
|
||||
_publishedContentTypeFactory.NotifyDataTypeChanges(changedIds);
|
||||
|
||||
base.Refresh(payloads);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
|
||||
public class ContentTypeUpdateHelper
|
||||
public static class ContentTypeUpdateHelper
|
||||
{
|
||||
public ContentTypeUpdateModel CreateContentTypeUpdateModel(IContentType contentType)
|
||||
public static ContentTypeUpdateModel CreateContentTypeUpdateModel(IContentType contentType)
|
||||
{
|
||||
var updateModel = new ContentTypeUpdateModel();
|
||||
var model = MapBaseProperties<ContentTypeUpdateModel>(contentType, updateModel);
|
||||
return model;
|
||||
}
|
||||
|
||||
private T MapBaseProperties<T>(IContentType contentType, T model) where T : ContentTypeModelBase
|
||||
private static T MapBaseProperties<T>(IContentType contentType, T model) where T : ContentTypeModelBase
|
||||
{
|
||||
model.Alias = contentType.Alias;
|
||||
model.Name = contentType.Name;
|
||||
|
||||
@@ -67,8 +67,7 @@ public abstract class UmbracoIntegrationTestWithContentEditing : UmbracoIntegrat
|
||||
Assert.IsTrue(contentTypeAttempt.Success);
|
||||
|
||||
var contentTypeResult = contentTypeAttempt.Result;
|
||||
ContentTypeUpdateHelper contentTypeUpdateHelper = new ContentTypeUpdateHelper();
|
||||
ContentTypeUpdateModel = contentTypeUpdateHelper.CreateContentTypeUpdateModel(contentTypeResult); ContentTypeUpdateModel.AllowedContentTypes = new[]
|
||||
ContentTypeUpdateModel = ContentTypeUpdateHelper.CreateContentTypeUpdateModel(contentTypeResult); ContentTypeUpdateModel.AllowedContentTypes = new[]
|
||||
{
|
||||
new ContentTypeSort(contentTypeResult.Key, 0, ContentTypeCreateModel.Alias),
|
||||
};
|
||||
|
||||
@@ -37,8 +37,7 @@ public class PublishedContentTypeCacheTests : UmbracoIntegrationTestWithContentE
|
||||
Assert.IsNotNull(contentType);
|
||||
Assert.AreEqual(1, ContentType.PropertyTypes.Count());
|
||||
// Update the content type
|
||||
ContentTypeUpdateHelper contentTypeUpdateHelper = new ContentTypeUpdateHelper();
|
||||
var updateModel = contentTypeUpdateHelper.CreateContentTypeUpdateModel(ContentType);
|
||||
var updateModel = ContentTypeUpdateHelper.CreateContentTypeUpdateModel(ContentType);
|
||||
updateModel.Properties = new List<ContentTypePropertyTypeModel>();
|
||||
await ContentTypeEditingService.UpdateAsync(ContentType, updateModel, Constants.Security.SuperUserKey);
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.ContentTypeEditing;
|
||||
using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
using Umbraco.Cms.Tests.Common.TestHelpers;
|
||||
using Umbraco.Cms.Tests.Common.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Testing;
|
||||
using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.PublishedContent;
|
||||
|
||||
[TestFixture]
|
||||
[UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)]
|
||||
public class PublishContentTypeFactoryTest : UmbracoIntegrationTest
|
||||
{
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder)
|
||||
{
|
||||
builder.AddNotificationHandler<ContentTypeChangedNotification, ContentTypeChangedDistributedCacheNotificationHandler>();
|
||||
builder.AddNotificationHandler<DataTypeSavedNotification, DataTypeSavedDistributedCacheNotificationHandler>();
|
||||
builder.Services.AddUnique<IServerMessenger, ContentEventsTests.LocalServerMessenger>();
|
||||
base.CustomTestSetup(builder);
|
||||
}
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeEditingService ContentTypeEditingService => GetRequiredService<IContentTypeEditingService>();
|
||||
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private IPublishedContentTypeFactory PublishedContentTypeFactory => GetRequiredService<IPublishedContentTypeFactory>();
|
||||
|
||||
[Test]
|
||||
public async Task Can_Update_Content_Type()
|
||||
{
|
||||
// Create a content type
|
||||
var template = TemplateBuilder.CreateTextPageTemplate("defaultTemplate");
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
var contentTypeCreateModel = ContentTypeEditingBuilder.CreateSimpleContentType("umbTextpage", "Textpage", defaultTemplateKey: template.Key);
|
||||
var contentTypeAttempt = await ContentTypeEditingService.CreateAsync(contentTypeCreateModel, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(contentTypeAttempt.Success);
|
||||
Assert.IsNotNull(contentTypeAttempt.Result);
|
||||
|
||||
// Fetch the content type to cache data types
|
||||
var contentType = contentTypeAttempt.Result;
|
||||
PublishedContentTypeFactory.CreateContentType(contentType);
|
||||
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.Build();
|
||||
var dataTypeCreateResult = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(dataTypeCreateResult.Success);
|
||||
|
||||
contentType.AddPropertyGroup("group", "Group");
|
||||
var propertyTypeAlias = "test";
|
||||
var propertyType = new PropertyTypeBuilder()
|
||||
.WithAlias(propertyTypeAlias)
|
||||
.WithDataTypeId(dataTypeCreateResult.Result.Id)
|
||||
.Build();
|
||||
propertyType.DataTypeKey = dataType.Key;
|
||||
|
||||
contentType.AddPropertyType(propertyType, "group", "Group");
|
||||
|
||||
// Update the content type
|
||||
var contentTypeUpdate = ContentTypeUpdateHelper.CreateContentTypeUpdateModel(contentType);
|
||||
var updateResult = await ContentTypeEditingService.UpdateAsync(contentType, contentTypeUpdate, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(updateResult.Success);
|
||||
|
||||
|
||||
var publishedContentType = PublishedContentTypeFactory.CreateContentType(updateResult.Result);
|
||||
Assert.That(publishedContentType.PropertyTypes.Where(x => x.Alias == propertyTypeAlias), Is.Not.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Can_Get_Updated_Datatype()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.Build();
|
||||
dataType.EditorUiAlias = "NotUpdated";
|
||||
var dataTypeCreateResult = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(dataTypeCreateResult.Success);
|
||||
var createdDataType = dataTypeCreateResult.Result;
|
||||
PublishedDataType createdPublishedDataType = PublishedContentTypeFactory.GetDataType(createdDataType.Id);
|
||||
Assert.That(createdPublishedDataType.EditorUiAlias, Is.EqualTo("NotUpdated"));
|
||||
|
||||
createdDataType.EditorUiAlias = "Updated";
|
||||
var dataTypeUpdateResult = await DataTypeService.UpdateAsync(createdDataType, Constants.Security.SuperUserKey);
|
||||
Assert.IsTrue(dataTypeUpdateResult.Success);
|
||||
var updatedPublishedDataType = PublishedContentTypeFactory.GetDataType(createdDataType.Id);
|
||||
Assert.That(updatedPublishedDataType.EditorUiAlias, Is.EqualTo("Updated"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user