Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V15: Refresh IPublishedContentTypeFactory when data types change #17180

Merged
merged 2 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
{
private readonly IContentTypeCommonRepository _contentTypeCommonRepository;
private readonly IPublishedModelFactory _publishedModelFactory;
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
private readonly IIdKeyMap _idKeyMap;

public ContentTypeCacheRefresher(
Expand All @@ -23,12 +24,14 @@
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;

Check notice on line 34 in src/Umbraco.Core/Cache/Refreshers/Implement/ContentTypeCacheRefresher.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (release/15.0)

ℹ Getting worse: Constructor Over-Injection

ContentTypeCacheRefresher increases from 7 to 8 arguments, threshold = 5. This constructor has too many arguments, indicating an object with low cohesion or missing function argument abstraction. Avoid adding more arguments.
}

#region Json
Expand Down Expand Up @@ -114,6 +117,8 @@
// 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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@
{
private readonly IIdKeyMap _idKeyMap;
private readonly IPublishedModelFactory _publishedModelFactory;
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;

public DataTypeCacheRefresher(
AppCaches appCaches,
IJsonSerializer serializer,
IIdKeyMap idKeyMap,
IEventAggregator eventAggregator,
ICacheRefresherNotificationFactory factory,
IPublishedModelFactory publishedModelFactory)
IPublishedModelFactory publishedModelFactory,
IPublishedContentTypeFactory publishedContentTypeFactory)
: base(appCaches, serializer, eventAggregator, factory)
{
_idKeyMap = idKeyMap;
_publishedModelFactory = publishedModelFactory;
_publishedContentTypeFactory = publishedContentTypeFactory;

Check notice on line 30 in src/Umbraco.Core/Cache/Refreshers/Implement/DataTypeCacheRefresher.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (release/15.0)

ℹ Getting worse: Constructor Over-Injection

DataTypeCacheRefresher increases from 6 to 7 arguments, threshold = 5. This constructor has too many arguments, indicating an object with low cohesion or missing function argument abstraction. Avoid adding more arguments.
}

#region Json
Expand Down Expand Up @@ -86,6 +89,9 @@
// 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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ protected async void CreateTestData()
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),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ public async Task Can_Get_Updated_Published_DocumentType_By_Key()
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);

Expand Down
Original file line number Diff line number Diff line change
@@ -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"));
}
}
Loading