2020-12-23 11:35:49 +01:00
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.Linq ;
2019-01-31 14:03:09 +01:00
using NUnit.Framework ;
2023-03-21 12:41:20 +01:00
using Umbraco.Cms.Core ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Configuration.Models ;
using Umbraco.Cms.Core.Events ;
using Umbraco.Cms.Core.Models ;
2021-05-11 14:33:49 +02:00
using Umbraco.Cms.Core.Notifications ;
2021-02-09 10:22:42 +01:00
using Umbraco.Cms.Core.Services ;
2021-04-09 13:43:39 +02:00
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement ;
2023-09-12 14:16:27 +02:00
using Umbraco.Cms.Tests.Common.Attributes ;
2021-02-10 14:45:44 +01:00
using Umbraco.Cms.Tests.Common.Builders ;
using Umbraco.Cms.Tests.Common.Testing ;
2021-02-11 08:30:27 +01:00
using Umbraco.Cms.Tests.Integration.Testing ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Services ;
[TestFixture]
[ UmbracoTest (
Database = UmbracoTestOptions . Database . NewSchemaPerTest ,
PublishedRepositoryEvents = true ,
WithApplication = true ,
Logger = UmbracoTestOptions . Logger . Console ) ]
2025-03-21 18:02:31 +01:00
internal sealed class ContentServiceNotificationTests : UmbracoIntegrationTest
2019-01-31 14:03:09 +01:00
{
2022-06-21 08:09:38 +02:00
[SetUp]
public void SetupTest ( )
2019-01-31 14:03:09 +01:00
{
2022-06-21 08:09:38 +02:00
ContentRepositoryBase . ThrowOnWarning = true ;
_globalSettings = new GlobalSettings ( ) ;
2020-12-23 11:35:49 +01:00
2022-06-21 08:09:38 +02:00
CreateTestData ( ) ;
}
2020-12-23 11:35:49 +01:00
2022-06-21 08:09:38 +02:00
[TearDown]
public void Teardown ( ) = > ContentRepositoryBase . ThrowOnWarning = false ;
2020-12-23 11:35:49 +01:00
2022-06-21 08:09:38 +02:00
private IContentTypeService ContentTypeService = > GetRequiredService < IContentTypeService > ( ) ;
2020-10-05 21:45:33 +02:00
2022-06-21 08:09:38 +02:00
private ContentService ContentService = > ( ContentService ) GetRequiredService < IContentService > ( ) ;
2020-08-24 16:06:09 +02:00
2023-01-26 13:34:11 +01:00
private ILanguageService LanguageService = > GetRequiredService < ILanguageService > ( ) ;
2020-12-23 11:35:49 +01:00
2022-06-21 08:09:38 +02:00
private IFileService FileService = > GetRequiredService < IFileService > ( ) ;
2020-10-07 11:23:31 +02:00
2022-06-21 08:09:38 +02:00
private GlobalSettings _globalSettings ;
private IContentType _contentType ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
protected override void CustomTestSetup ( IUmbracoBuilder builder ) = > builder
. AddNotificationHandler < ContentSavingNotification , ContentNotificationHandler > ( )
. AddNotificationHandler < ContentSavedNotification , ContentNotificationHandler > ( )
. AddNotificationHandler < ContentPublishingNotification , ContentNotificationHandler > ( )
. AddNotificationHandler < ContentPublishedNotification , ContentNotificationHandler > ( )
. AddNotificationHandler < ContentUnpublishingNotification , ContentNotificationHandler > ( )
2024-12-09 11:36:48 +01:00
. AddNotificationHandler < ContentUnpublishedNotification , ContentNotificationHandler > ( )
. AddNotificationHandler < ContentTreeChangeNotification , ContentNotificationHandler > ( ) ;
2020-10-07 11:23:31 +02:00
2022-06-21 08:09:38 +02:00
private void CreateTestData ( )
{
var template = TemplateBuilder . CreateTextPageTemplate ( ) ;
FileService . SaveTemplate ( template ) ; // else, FK violation on contentType!
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
_contentType = ContentTypeBuilder . CreateTextPageContentType ( defaultTemplateId : template . Id ) ;
ContentTypeService . Save ( _contentType ) ;
}
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
[Test]
2023-01-26 13:34:11 +01:00
public async Task Saving_Culture ( )
2022-06-21 08:09:38 +02:00
{
2023-03-21 12:41:20 +01:00
await LanguageService . CreateAsync ( new Language ( "fr-FR" , "French (France)" ) , Constants . Security . SuperUserKey ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
_contentType . Variations = ContentVariation . Culture ;
foreach ( var propertyType in _contentType . PropertyTypes )
{
propertyType . Variations = ContentVariation . Culture ;
}
2020-12-23 11:35:49 +01:00
2022-06-21 08:09:38 +02:00
ContentTypeService . Save ( _contentType ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
IContent document = new Content ( "content" , - 1 , _contentType ) ;
document . SetCultureName ( "hello" , "en-US" ) ;
document . SetCultureName ( "bonjour" , "fr-FR" ) ;
ContentService . Save ( document ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
// re-get - dirty properties need resetting
document = ContentService . GetById ( document . Id ) ;
2019-02-06 16:10:20 +11:00
2022-06-21 08:09:38 +02:00
// properties: title, bodyText, keywords, description
document . SetValue ( "title" , "title-en" , "en-US" ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
var savingWasCalled = false ;
var savedWasCalled = false ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavingContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( document , saved ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( notification . IsSavingCulture ( saved , "en-US" ) ) ;
Assert . IsFalse ( notification . IsSavingCulture ( saved , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
savingWasCalled = true ;
} ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavedContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( document , saved ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( notification . HasSavedCulture ( saved , "en-US" ) ) ;
Assert . IsFalse ( notification . HasSavedCulture ( saved , "fr-FR" ) ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
savedWasCalled = true ;
} ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
try
{
ContentService . Save ( document ) ;
Assert . IsTrue ( savingWasCalled ) ;
Assert . IsTrue ( savedWasCalled ) ;
2019-01-31 14:03:09 +01:00
}
2022-06-21 08:09:38 +02:00
finally
2019-02-21 12:08:00 +11:00
{
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavingContent = null ;
ContentNotificationHandler . SavedContent = null ;
}
}
2019-12-09 14:12:06 +01:00
2022-06-21 08:09:38 +02:00
[Test]
public void Saving_Set_Value ( )
{
IContent document = new Content ( "content" , - 1 , _contentType ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
var savingWasCalled = false ;
var savedWasCalled = false ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavingContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( document . GetValue < string > ( "title" ) . IsNullOrWhiteSpace ( ) ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
saved . SetValue ( "title" , "title" ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
savingWasCalled = true ;
} ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavedContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( "title" , document . GetValue < string > ( "title" ) ) ;
2019-12-09 14:12:06 +01:00
2022-06-21 08:09:38 +02:00
// we're only dealing with invariant here
var propValue = saved . Properties [ "title" ] . Values . First ( x = > x . Culture = = null & & x . Segment = = null ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
Assert . AreEqual ( "title" , propValue . EditedValue ) ;
Assert . IsNull ( propValue . PublishedValue ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
savedWasCalled = true ;
} ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
try
2019-01-31 14:03:09 +01:00
{
2022-06-21 08:09:38 +02:00
ContentService . Save ( document ) ;
Assert . IsTrue ( savingWasCalled ) ;
Assert . IsTrue ( savedWasCalled ) ;
}
finally
{
ContentNotificationHandler . SavingContent = null ;
ContentNotificationHandler . SavedContent = null ;
}
}
2020-12-23 11:35:49 +01:00
2024-12-09 11:36:48 +01:00
[Test]
public void Publishing_Invariant ( )
{
IContent document = new Content ( "content" , - 1 , _contentType ) ;
2025-01-20 14:00:18 +01:00
ContentService . Save ( document ) ;
2024-12-09 11:36:48 +01:00
var treeChangeWasCalled = false ;
ContentNotificationHandler . TreeChange + = notification = >
{
var change = notification . Changes . FirstOrDefault ( ) ;
var publishedCultures = change ? . PublishedCultures ? . ToArray ( ) ;
Assert . IsNotNull ( publishedCultures ) ;
Assert . AreEqual ( 1 , publishedCultures . Length ) ;
Assert . IsTrue ( publishedCultures . InvariantContains ( "*" ) ) ;
Assert . IsNull ( change . UnpublishedCultures ) ;
treeChangeWasCalled = true ;
} ;
try
{
2025-01-20 14:00:18 +01:00
ContentService . Publish ( document , [ "*" ] ) ;
2024-12-09 11:36:48 +01:00
Assert . IsTrue ( treeChangeWasCalled ) ;
}
finally
{
ContentNotificationHandler . TreeChange = null ;
}
}
[Test]
public void Unpublishing_Invariant ( )
{
IContent document = new Content ( "content" , - 1 , _contentType ) ;
2025-01-20 14:00:18 +01:00
ContentService . Save ( document ) ;
ContentService . Publish ( document , [ "*" ] ) ;
2024-12-09 11:36:48 +01:00
var treeChangeWasCalled = false ;
ContentNotificationHandler . TreeChange + = notification = >
{
var change = notification . Changes . FirstOrDefault ( ) ;
Assert . IsNull ( change ? . PublishedCultures ) ;
var unpublishedCultures = change ? . UnpublishedCultures ? . ToArray ( ) ;
Assert . IsNotNull ( unpublishedCultures ) ;
Assert . AreEqual ( 1 , unpublishedCultures . Length ) ;
Assert . IsTrue ( unpublishedCultures . InvariantContains ( "*" ) ) ;
treeChangeWasCalled = true ;
} ;
try
{
ContentService . Unpublish ( document ) ;
Assert . IsTrue ( treeChangeWasCalled ) ;
}
finally
{
ContentNotificationHandler . TreeChange = null ;
}
}
2022-06-21 08:09:38 +02:00
[Test]
2023-01-26 13:34:11 +01:00
public async Task Publishing_Culture ( )
2022-06-21 08:09:38 +02:00
{
2023-03-21 12:41:20 +01:00
await LanguageService . CreateAsync ( new Language ( "fr-FR" , "French (France)" ) , Constants . Security . SuperUserKey ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
_contentType . Variations = ContentVariation . Culture ;
foreach ( var propertyType in _contentType . PropertyTypes )
{
propertyType . Variations = ContentVariation . Culture ;
}
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
ContentTypeService . Save ( _contentType ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
IContent document = new Content ( "content" , - 1 , _contentType ) ;
document . SetCultureName ( "hello" , "en-US" ) ;
document . SetCultureName ( "bonjour" , "fr-FR" ) ;
ContentService . Save ( document ) ;
2019-02-06 16:10:20 +11:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( document . IsCulturePublished ( "fr-FR" ) ) ;
Assert . IsFalse ( document . IsCulturePublished ( "en-US" ) ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
// re-get - dirty properties need resetting
document = ContentService . GetById ( document . Id ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
var publishingWasCalled = false ;
var publishedWasCalled = false ;
2024-12-09 11:36:48 +01:00
var treeChangeWasCalled = false ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . PublishingContent + = notification = >
{
var publishing = notification . PublishedEntities . First ( ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( document , publishing ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( notification . IsPublishingCulture ( publishing , "en-US" ) ) ;
Assert . IsTrue ( notification . IsPublishingCulture ( publishing , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
publishingWasCalled = true ;
} ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . PublishedContent + = notification = >
{
var published = notification . PublishedEntities . First ( ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( document , published ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( notification . HasPublishedCulture ( published , "en-US" ) ) ;
Assert . IsTrue ( notification . HasPublishedCulture ( published , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
publishedWasCalled = true ;
} ;
2019-01-31 14:03:09 +01:00
2024-12-09 11:36:48 +01:00
ContentNotificationHandler . TreeChange + = notification = >
{
var change = notification . Changes . FirstOrDefault ( ) ;
var publishedCultures = change ? . PublishedCultures ? . ToArray ( ) ;
Assert . IsNotNull ( publishedCultures ) ;
Assert . AreEqual ( 1 , publishedCultures . Length ) ;
Assert . IsTrue ( publishedCultures . InvariantContains ( "fr-FR" ) ) ;
Assert . IsNull ( change . UnpublishedCultures ) ;
treeChangeWasCalled = true ;
} ;
2022-06-21 08:09:38 +02:00
try
{
2023-11-22 12:52:08 +01:00
ContentService . Publish ( document , new [ ] { "fr-FR" } ) ;
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( publishingWasCalled ) ;
Assert . IsTrue ( publishedWasCalled ) ;
2024-12-09 11:36:48 +01:00
Assert . IsTrue ( treeChangeWasCalled ) ;
2019-01-31 14:03:09 +01:00
}
2022-06-21 08:09:38 +02:00
finally
2019-02-21 12:08:00 +11:00
{
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . PublishingContent = null ;
ContentNotificationHandler . PublishedContent = null ;
2024-12-09 11:36:48 +01:00
ContentNotificationHandler . TreeChange = null ;
2022-06-21 08:09:38 +02:00
}
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
document = ContentService . GetById ( document . Id ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
// ensure it works and does not throw
Assert . IsTrue ( document . IsCulturePublished ( "fr-FR" ) ) ;
Assert . IsFalse ( document . IsCulturePublished ( "en-US" ) ) ;
}
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
[Test]
public void Publishing_Set_Value ( )
{
IContent document = new Content ( "content" , - 1 , _contentType ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
var savingWasCalled = false ;
var savedWasCalled = false ;
2023-11-22 12:52:08 +01:00
var publishingWasCalled = false ;
var publishedWasCalled = false ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavingContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( document . GetValue < string > ( "title" ) . IsNullOrWhiteSpace ( ) ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
saved . SetValue ( "title" , "title" ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
savingWasCalled = true ;
} ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavedContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( "title" , document . GetValue < string > ( "title" ) ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
// We're only dealing with invariant here.
var propValue = saved . Properties [ "title" ] . Values . First ( x = > x . Culture = = null & & x . Segment = = null ) ;
Assert . AreEqual ( "title" , propValue . EditedValue ) ;
2023-11-22 12:52:08 +01:00
Assert . AreEqual ( null , propValue . PublishedValue ) ;
2022-06-21 08:09:38 +02:00
savedWasCalled = true ;
} ;
2019-02-21 14:46:14 +11:00
2023-11-22 12:52:08 +01:00
ContentNotificationHandler . PublishingContent = notification = >
{
var publishing = notification . PublishedEntities . First ( ) ;
Assert . AreEqual ( "title" , publishing . GetValue < string > ( "title" ) ) ;
publishingWasCalled = true ;
} ;
ContentNotificationHandler . PublishedContent = notification = >
{
var published = notification . PublishedEntities . First ( ) ;
Assert . AreSame ( "title" , document . GetValue < string > ( "title" ) ) ;
// We're only dealing with invariant here.
var propValue = published . Properties [ "title" ] . Values . First ( x = > x . Culture = = null & & x . Segment = = null ) ;
Assert . AreEqual ( "title" , propValue . EditedValue ) ;
Assert . AreEqual ( "title" , propValue . PublishedValue ) ;
publishedWasCalled = true ;
} ;
2022-06-21 08:09:38 +02:00
try
2019-02-21 14:46:14 +11:00
{
2023-11-22 12:52:08 +01:00
ContentService . Save ( document ) ;
ContentService . Publish ( document , document . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( savingWasCalled ) ;
Assert . IsTrue ( savedWasCalled ) ;
2023-11-22 12:52:08 +01:00
Assert . IsTrue ( publishingWasCalled ) ;
Assert . IsTrue ( publishedWasCalled ) ;
2022-06-21 08:09:38 +02:00
}
finally
{
ContentNotificationHandler . SavingContent = null ;
ContentNotificationHandler . SavedContent = null ;
2023-11-22 12:52:08 +01:00
ContentNotificationHandler . PublishingContent = null ;
ContentNotificationHandler . PublishedContent = null ;
2022-06-21 08:09:38 +02:00
}
}
2019-02-21 14:46:14 +11:00
2022-06-21 08:09:38 +02:00
[Test]
public void Publishing_Set_Mandatory_Value ( )
{
var titleProperty = _contentType . PropertyTypes . First ( x = > x . Alias = = "title" ) ;
titleProperty . Mandatory = true ; // make this required!
ContentTypeService . Save ( _contentType ) ;
2019-02-21 14:46:14 +11:00
2022-06-21 08:09:38 +02:00
IContent document = new Content ( "content" , - 1 , _contentType ) ;
2019-02-21 14:46:14 +11:00
2023-11-22 12:52:08 +01:00
ContentService . Save ( document ) ;
var result = ContentService . Publish ( document , document . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( result . Success ) ;
Assert . AreEqual ( "title" , result . InvalidProperties . First ( ) . Alias ) ;
2019-02-21 14:46:14 +11:00
2022-06-21 08:09:38 +02:00
// when a service operation fails, the object is dirty and should not be re-used,
// re-create it
document = new Content ( "content" , - 1 , _contentType ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
var savingWasCalled = false ;
2019-02-21 14:46:14 +11:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . SavingContent = notification = >
{
var saved = notification . SavedEntities . First ( ) ;
2019-02-21 14:46:14 +11:00
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( document . GetValue < string > ( "title" ) . IsNullOrWhiteSpace ( ) ) ;
2019-02-21 14:46:14 +11:00
2022-06-21 08:09:38 +02:00
saved . SetValue ( "title" , "title" ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
savingWasCalled = true ;
} ;
2019-02-21 12:08:00 +11:00
2022-06-21 08:09:38 +02:00
try
2019-01-31 14:03:09 +01:00
{
2023-11-22 12:52:08 +01:00
ContentService . Save ( document ) ;
result = ContentService . Publish ( document , document . AvailableCultures . ToArray ( ) ) ;
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( result
. Success ) ; // will succeed now because we were able to specify the required value in the Saving event
Assert . IsTrue ( savingWasCalled ) ;
}
finally
{
ContentNotificationHandler . SavingContent = null ;
}
}
2020-12-23 11:35:49 +01:00
2022-06-21 08:09:38 +02:00
[Test]
2023-09-12 14:16:27 +02:00
[LongRunning]
2023-01-26 13:34:11 +01:00
public async Task Unpublishing_Culture ( )
2022-06-21 08:09:38 +02:00
{
2023-03-21 12:41:20 +01:00
await LanguageService . CreateAsync ( new Language ( "fr-FR" , "French (France)" ) , Constants . Security . SuperUserKey ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
_contentType . Variations = ContentVariation . Culture ;
foreach ( var propertyType in _contentType . PropertyTypes )
{
propertyType . Variations = ContentVariation . Culture ;
}
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
ContentTypeService . Save ( _contentType ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
IContent document = new Content ( "content" , - 1 , _contentType ) ;
document . SetCultureName ( "hello" , "en-US" ) ;
document . SetCultureName ( "bonjour" , "fr-FR" ) ;
2023-11-22 12:52:08 +01:00
ContentService . Save ( document ) ;
ContentService . Publish ( document , document . AvailableCultures . ToArray ( ) ) ;
2019-02-06 16:10:20 +11:00
2022-06-21 08:09:38 +02:00
Assert . IsTrue ( document . IsCulturePublished ( "fr-FR" ) ) ;
Assert . IsTrue ( document . IsCulturePublished ( "en-US" ) ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
// re-get - dirty properties need resetting
document = ContentService . GetById ( document . Id ) ;
2021-03-02 19:11:39 +01:00
2022-06-21 08:09:38 +02:00
document . UnpublishCulture ( "fr-FR" ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
var publishingWasCalled = false ;
var publishedWasCalled = false ;
2024-12-09 11:36:48 +01:00
var treeChangeWasCalled = false ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
// TODO: revisit this - it was migrated when removing static events, but the expected result seems illogic - why does this test bind to Published and not Unpublished?
2021-03-02 19:11:39 +01:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . PublishingContent + = notification = >
{
var published = notification . PublishedEntities . First ( ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( document , published ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( notification . IsPublishingCulture ( published , "en-US" ) ) ;
Assert . IsFalse ( notification . IsPublishingCulture ( published , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( notification . IsUnpublishingCulture ( published , "en-US" ) ) ;
Assert . IsTrue ( notification . IsUnpublishingCulture ( published , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
publishingWasCalled = true ;
} ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . PublishedContent + = notification = >
{
var published = notification . PublishedEntities . First ( ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . AreSame ( document , published ) ;
2021-03-02 19:11:39 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( notification . HasPublishedCulture ( published , "en-US" ) ) ;
Assert . IsFalse ( notification . HasPublishedCulture ( published , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( notification . HasUnpublishedCulture ( published , "en-US" ) ) ;
Assert . IsTrue ( notification . HasUnpublishedCulture ( published , "fr-FR" ) ) ;
2019-01-31 14:03:09 +01:00
2022-06-21 08:09:38 +02:00
publishedWasCalled = true ;
} ;
2019-01-31 14:03:09 +01:00
2024-12-09 11:36:48 +01:00
ContentNotificationHandler . TreeChange + = notification = >
{
var change = notification . Changes . FirstOrDefault ( ) ;
var unpublishedCultures = change ? . UnpublishedCultures ? . ToArray ( ) ;
Assert . IsNotNull ( unpublishedCultures ) ;
Assert . AreEqual ( 1 , unpublishedCultures . Length ) ;
Assert . IsTrue ( unpublishedCultures . InvariantContains ( "fr-FR" ) ) ;
Assert . IsNull ( change . PublishedCultures ) ;
treeChangeWasCalled = true ;
} ;
2022-06-21 08:09:38 +02:00
try
{
ContentService . CommitDocumentChanges ( document ) ;
Assert . IsTrue ( publishingWasCalled ) ;
Assert . IsTrue ( publishedWasCalled ) ;
2024-12-09 11:36:48 +01:00
Assert . IsTrue ( treeChangeWasCalled ) ;
2019-01-31 14:03:09 +01:00
}
2022-06-21 08:09:38 +02:00
finally
2021-03-02 14:15:26 +01:00
{
2022-06-21 08:09:38 +02:00
ContentNotificationHandler . PublishingContent = null ;
ContentNotificationHandler . PublishedContent = null ;
2024-12-09 11:36:48 +01:00
ContentNotificationHandler . TreeChange = null ;
2022-06-21 08:09:38 +02:00
}
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
document = ContentService . GetById ( document . Id ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
Assert . IsFalse ( document . IsCulturePublished ( "fr-FR" ) ) ;
Assert . IsTrue ( document . IsCulturePublished ( "en-US" ) ) ;
}
2021-03-02 14:15:26 +01:00
2025-03-21 18:02:31 +01:00
internal sealed class ContentNotificationHandler :
2022-06-21 08:09:38 +02:00
INotificationHandler < ContentSavingNotification > ,
INotificationHandler < ContentSavedNotification > ,
INotificationHandler < ContentPublishingNotification > ,
INotificationHandler < ContentPublishedNotification > ,
INotificationHandler < ContentUnpublishingNotification > ,
2024-12-09 11:36:48 +01:00
INotificationHandler < ContentUnpublishedNotification > ,
INotificationHandler < ContentTreeChangeNotification >
2022-06-21 08:09:38 +02:00
{
public static Action < ContentSavingNotification > SavingContent { get ; set ; }
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public static Action < ContentSavedNotification > SavedContent { get ; set ; }
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public static Action < ContentPublishingNotification > PublishingContent { get ; set ; }
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public static Action < ContentPublishedNotification > PublishedContent { get ; set ; }
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public static Action < ContentUnpublishingNotification > UnpublishingContent { get ; set ; }
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public static Action < ContentUnpublishedNotification > UnpublishedContent { get ; set ; }
2021-03-02 14:15:26 +01:00
2024-12-09 11:36:48 +01:00
public static Action < ContentTreeChangeNotification > TreeChange { get ; set ; }
2022-06-21 08:09:38 +02:00
public void Handle ( ContentPublishedNotification notification ) = > PublishedContent ? . Invoke ( notification ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public void Handle ( ContentPublishingNotification notification ) = > PublishingContent ? . Invoke ( notification ) ;
2021-03-02 14:15:26 +01:00
2022-06-21 08:09:38 +02:00
public void Handle ( ContentSavedNotification notification ) = > SavedContent ? . Invoke ( notification ) ;
public void Handle ( ContentSavingNotification notification ) = > SavingContent ? . Invoke ( notification ) ;
public void Handle ( ContentUnpublishedNotification notification ) = > UnpublishedContent ? . Invoke ( notification ) ;
public void Handle ( ContentUnpublishingNotification notification ) = > UnpublishingContent ? . Invoke ( notification ) ;
2024-12-09 11:36:48 +01:00
public void Handle ( ContentTreeChangeNotification notification ) = > TreeChange ? . Invoke ( notification ) ;
2019-01-31 14:03:09 +01:00
}
}