11// Copyright (c) Umbraco.
22// See LICENSE for more details.
33
4- using System . Collections . Generic ;
5- using System . Linq ;
4+ using Microsoft . Extensions . Logging ;
5+ using Moq ;
66using NUnit . Framework ;
7+ using Umbraco . Cms . Core . Cache ;
78using Umbraco . Cms . Core . Models ;
89using Umbraco . Cms . Core . Persistence . Repositories ;
910using Umbraco . Cms . Core . Services ;
11+ using Umbraco . Cms . Infrastructure . Persistence . Repositories . Implement ;
12+ using Umbraco . Cms . Infrastructure . Scoping ;
1013using Umbraco . Cms . Tests . Common . Testing ;
1114using Umbraco . Cms . Tests . Integration . Testing ;
1215
@@ -21,6 +24,15 @@ public class DictionaryRepositoryTest : UmbracoIntegrationTest
2124
2225 private IDictionaryRepository CreateRepository ( ) => GetRequiredService < IDictionaryRepository > ( ) ;
2326
27+ private IDictionaryRepository CreateRepositoryWithCache ( AppCaches cache ) =>
28+
29+ // Create a repository with a real runtime cache.
30+ new DictionaryRepository (
31+ GetRequiredService < IScopeAccessor > ( ) ,
32+ cache ,
33+ GetRequiredService < ILogger < DictionaryRepository > > ( ) ,
34+ GetRequiredService < ILoggerFactory > ( ) ) ;
35+
2436 [ Test ]
2537 public void Can_Perform_Get_By_Key_On_DictionaryRepository ( )
2638 {
@@ -395,6 +407,134 @@ public void Can_Perform_GetDictionaryItemKeyMap_On_DictionaryRepository()
395407 }
396408 }
397409
410+ [ Test ]
411+ public void Can_Perform_Cached_Request_For_Existing_Value_By_Key_On_DictionaryRepository_With_Cache ( )
412+ {
413+ var cache = AppCaches . Create ( Mock . Of < IRequestCache > ( ) ) ;
414+ var repository = CreateRepositoryWithCache ( cache ) ;
415+
416+ using ( ScopeProvider . CreateScope ( ) )
417+ {
418+ var dictionaryItem = repository . Get ( "Read More" ) ;
419+
420+ Assert . AreEqual ( "Read More" , dictionaryItem . Translations . Single ( x => x . LanguageIsoCode == "en-US" ) . Value ) ;
421+ }
422+
423+ // Modify the value directly in the database. This won't be reflected in the repository cache and hence if the cache
424+ // is working as expected we should get the same value as above.
425+ using ( var scope = ScopeProvider . CreateScope ( ) )
426+ {
427+ scope . Database . Execute ( "UPDATE cmsLanguageText SET value = 'Read More (updated)' WHERE value = 'Read More' and LanguageId = 1" ) ;
428+ scope . Complete ( ) ;
429+ }
430+
431+ using ( ScopeProvider . CreateScope ( ) )
432+ {
433+ var dictionaryItem = repository . Get ( "Read More" ) ;
434+
435+ Assert . AreEqual ( "Read More" , dictionaryItem . Translations . Single ( x => x . LanguageIsoCode == "en-US" ) . Value ) ;
436+ }
437+
438+ cache . IsolatedCaches . ClearCache < IDictionaryItem > ( ) ;
439+ using ( ScopeProvider . CreateScope ( ) )
440+ {
441+ var dictionaryItem = repository . Get ( "Read More" ) ;
442+
443+ Assert . AreEqual ( "Read More (updated)" , dictionaryItem . Translations . Single ( x => x . LanguageIsoCode == "en-US" ) . Value ) ;
444+ }
445+ }
446+
447+ [ Test ]
448+ public void Can_Perform_Cached_Request_For_NonExisting_Value_By_Key_On_DictionaryRepository_With_Cache ( )
449+ {
450+ var cache = AppCaches . Create ( Mock . Of < IRequestCache > ( ) ) ;
451+ var repository = CreateRepositoryWithCache ( cache ) ;
452+
453+ using ( ScopeProvider . CreateScope ( ) )
454+ {
455+ var dictionaryItem = repository . Get ( "Read More Updated" ) ;
456+
457+ Assert . IsNull ( dictionaryItem ) ;
458+ }
459+
460+ // Modify the value directly in the database such that it now exists. This won't be reflected in the repository cache and hence if the cache
461+ // is working as expected we should get the same null value as above.
462+ using ( var scope = ScopeProvider . CreateScope ( ) )
463+ {
464+ scope . Database . Execute ( "UPDATE cmsDictionary SET [key] = 'Read More Updated' WHERE [key] = 'Read More'" ) ;
465+ scope . Complete ( ) ;
466+ }
467+
468+ using ( ScopeProvider . CreateScope ( ) )
469+ {
470+ var dictionaryItem = repository . Get ( "Read More Updated" ) ;
471+
472+ Assert . IsNull ( dictionaryItem ) ;
473+ }
474+
475+ cache . IsolatedCaches . ClearCache < IDictionaryItem > ( ) ;
476+ using ( ScopeProvider . CreateScope ( ) )
477+ {
478+ var dictionaryItem = repository . Get ( "Read More Updated" ) ;
479+
480+ Assert . IsNotNull ( dictionaryItem ) ;
481+ }
482+ }
483+
484+ [ Test ]
485+ public void Cannot_Perform_Cached_Request_For_Existing_Value_By_Key_On_DictionaryRepository_Without_Cache ( )
486+ {
487+ var repository = CreateRepository ( ) ;
488+
489+ using ( ScopeProvider . CreateScope ( ) )
490+ {
491+ var dictionaryItem = repository . Get ( "Read More" ) ;
492+
493+ Assert . AreEqual ( "Read More" , dictionaryItem . Translations . Single ( x => x . LanguageIsoCode == "en-US" ) . Value ) ;
494+ }
495+
496+ // Modify the value directly in the database. As we don't have caching enabled on the repository we should get the new value.
497+ using ( var scope = ScopeProvider . CreateScope ( ) )
498+ {
499+ scope . Database . Execute ( "UPDATE cmsLanguageText SET value = 'Read More (updated)' WHERE value = 'Read More' and LanguageId = 1" ) ;
500+ scope . Complete ( ) ;
501+ }
502+
503+ using ( ScopeProvider . CreateScope ( ) )
504+ {
505+ var dictionaryItem = repository . Get ( "Read More" ) ;
506+
507+ Assert . AreEqual ( "Read More (updated)" , dictionaryItem . Translations . Single ( x => x . LanguageIsoCode == "en-US" ) . Value ) ;
508+ }
509+ }
510+
511+ [ Test ]
512+ public void Cannot_Perform_Cached_Request_For_NonExisting_Value_By_Key_On_DictionaryRepository_Without_Cache ( )
513+ {
514+ var repository = CreateRepository ( ) ;
515+
516+ using ( ScopeProvider . CreateScope ( ) )
517+ {
518+ var dictionaryItem = repository . Get ( "Read More Updated" ) ;
519+
520+ Assert . IsNull ( dictionaryItem ) ;
521+ }
522+
523+ // Modify the value directly in the database such that it now exists. As we don't have caching enabled on the repository we should get the new value.
524+ using ( var scope = ScopeProvider . CreateScope ( ) )
525+ {
526+ scope . Database . Execute ( "UPDATE cmsDictionary SET [key] = 'Read More Updated' WHERE [key] = 'Read More'" ) ;
527+ scope . Complete ( ) ;
528+ }
529+
530+ using ( ScopeProvider . CreateScope ( ) )
531+ {
532+ var dictionaryItem = repository . Get ( "Read More Updated" ) ;
533+
534+ Assert . IsNotNull ( dictionaryItem ) ;
535+ }
536+ }
537+
398538 public void CreateTestData ( )
399539 {
400540 var localizationService = GetRequiredService < ILocalizationService > ( ) ;
0 commit comments