11using NUnit . Framework ;
22using Umbraco . Cms . Core ;
3+ using Umbraco . Cms . Core . Cache ;
34using Umbraco . Cms . Core . Models ;
45using Umbraco . Cms . Core . Models . Blocks ;
6+ using Umbraco . Cms . Core . Notifications ;
57using Umbraco . Cms . Core . PropertyEditors ;
8+ using Umbraco . Cms . Core . PublishedCache ;
69using Umbraco . Cms . Core . Serialization ;
710using Umbraco . Cms . Core . Services ;
11+ using Umbraco . Cms . Core . Sync ;
812using Umbraco . Cms . Tests . Common . Builders ;
13+ using Umbraco . Cms . Tests . Common . Builders . Extensions ;
914using Umbraco . Cms . Tests . Common . Testing ;
1015using Umbraco . Cms . Tests . Integration . Testing ;
16+ using Umbraco . Cms . Tests . Integration . Umbraco . Infrastructure . Services ;
1117
1218namespace Umbraco . Cms . Tests . Integration . Umbraco . Infrastructure . PropertyEditors ;
1319
@@ -23,6 +29,14 @@ internal sealed class RichTextPropertyEditorTests : UmbracoIntegrationTest
2329
2430 private IJsonSerializer JsonSerializer => GetRequiredService < IJsonSerializer > ( ) ;
2531
32+ private IPublishedContentCache PublishedContentCache => GetRequiredService < IPublishedContentCache > ( ) ;
33+
34+ protected override void CustomTestSetup ( IUmbracoBuilder builder )
35+ {
36+ builder . AddNotificationHandler < ContentTreeChangeNotification , ContentTreeChangeDistributedCacheNotificationHandler > ( ) ;
37+ builder . Services . AddUnique < IServerMessenger , ContentEventsTests . LocalServerMessenger > ( ) ;
38+ }
39+
2640 [ Test ]
2741 public void Can_Use_Markup_String_As_Value ( )
2842 {
@@ -180,4 +194,103 @@ public void Can_Track_Block_Tags()
180194 Assert . IsNotNull ( tags . Single ( tag => tag . Text == "Tag Two" ) ) ;
181195 Assert . IsNotNull ( tags . Single ( tag => tag . Text == "Tag Three" ) ) ;
182196 }
197+
198+ [ TestCase ( null , false ) ]
199+ [ TestCase ( "" , false ) ]
200+ [ TestCase ( """{"markup":"","blocks":null}""" , false ) ]
201+ [ TestCase ( """{"markup":"<p></p>","blocks":null}""" , false ) ]
202+ [ TestCase ( "abc" , true ) ]
203+ [ TestCase ( """{"markup":"abc","blocks":null}""" , true ) ]
204+ public async Task Can_Handle_Empty_Value_Representations_For_Invariant_Content ( string ? rteValue , bool expectedHasValue )
205+ {
206+ var contentType = await CreateContentTypeForEmptyValueTests ( ) ;
207+
208+ var content = new ContentBuilder ( )
209+ . WithContentType ( contentType )
210+ . WithName ( "Page" )
211+ . WithPropertyValues (
212+ new
213+ {
214+ rte = rteValue
215+ } )
216+ . Build ( ) ;
217+
218+ var contentResult = ContentService . Save ( content ) ;
219+ Assert . IsTrue ( contentResult . Success ) ;
220+
221+ var publishResult = ContentService . Publish ( content , [ ] ) ;
222+ Assert . IsTrue ( publishResult . Success ) ;
223+
224+ var publishedContent = await PublishedContentCache . GetByIdAsync ( content . Key ) ;
225+ Assert . IsNotNull ( publishedContent ) ;
226+
227+ var publishedProperty = publishedContent . Properties . First ( property => property . Alias == "rte" ) ;
228+ Assert . AreEqual ( expectedHasValue , publishedProperty . HasValue ( ) ) ;
229+
230+ Assert . AreEqual ( expectedHasValue , publishedContent . HasValue ( "rte" ) ) ;
231+ }
232+
233+ [ TestCase ( null , false ) ]
234+ [ TestCase ( "" , false ) ]
235+ [ TestCase ( """{"markup":"","blocks":null}""" , false ) ]
236+ [ TestCase ( """{"markup":"<p></p>","blocks":null}""" , false ) ]
237+ [ TestCase ( "abc" , true ) ]
238+ [ TestCase ( """{"markup":"abc","blocks":null}""" , true ) ]
239+ public async Task Can_Handle_Empty_Value_Representations_For_Variant_Content ( string ? rteValue , bool expectedHasValue )
240+ {
241+ var contentType = await CreateContentTypeForEmptyValueTests ( ContentVariation . Culture ) ;
242+
243+ var content = new ContentBuilder ( )
244+ . WithContentType ( contentType )
245+ . WithName ( "Page" )
246+ . WithCultureName ( "en-US" , "Page" )
247+ . WithPropertyValues (
248+ new
249+ {
250+ rte = rteValue
251+ } ,
252+ "en-US" )
253+ . Build ( ) ;
254+
255+ var contentResult = ContentService . Save ( content ) ;
256+ Assert . IsTrue ( contentResult . Success ) ;
257+
258+ var publishResult = ContentService . Publish ( content , [ "en-US" ] ) ;
259+ Assert . IsTrue ( publishResult . Success ) ;
260+
261+ var publishedContent = await PublishedContentCache . GetByIdAsync ( content . Key ) ;
262+ Assert . IsNotNull ( publishedContent ) ;
263+
264+ var publishedProperty = publishedContent . Properties . First ( property => property . Alias == "rte" ) ;
265+ Assert . AreEqual ( expectedHasValue , publishedProperty . HasValue ( "en-US" ) ) ;
266+
267+ Assert . AreEqual ( expectedHasValue , publishedContent . HasValue ( "rte" , "en-US" ) ) ;
268+ }
269+
270+ private async Task < IContentType > CreateContentTypeForEmptyValueTests ( ContentVariation contentVariation = ContentVariation . Nothing )
271+ {
272+ var contentType = new ContentTypeBuilder ( )
273+ . WithAlias ( "myPage" )
274+ . WithName ( "My Page" )
275+ . WithContentVariation ( contentVariation )
276+ . AddPropertyGroup ( )
277+ . WithAlias ( "content" )
278+ . WithName ( "Content" )
279+ . WithSupportsPublishing ( true )
280+ . AddPropertyType ( )
281+ . WithPropertyEditorAlias ( Constants . PropertyEditors . Aliases . RichText )
282+ . WithDataTypeId ( Constants . DataTypes . RichtextEditor )
283+ . WithValueStorageType ( ValueStorageType . Ntext )
284+ . WithAlias ( "rte" )
285+ . WithName ( "RTE" )
286+ . WithVariations ( contentVariation )
287+ . Done ( )
288+ . Done ( )
289+ . Build ( ) ;
290+
291+ var contentTypeResult = await ContentTypeService . CreateAsync ( contentType , Constants . Security . SuperUserKey ) ;
292+ Assert . IsTrue ( contentTypeResult . Success ) ;
293+
294+ return contentType ;
295+ }
183296}
0 commit comments