From 082e703863be9fe3062aae591efe19554e1e2ee4 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 18 Nov 2021 13:34:10 +0100 Subject: [PATCH] Migrated / Rewritten ScopedNuCacheTests (#11636) * Migrated / Rewritten ScopedNuCacheTests * Cleanup Co-authored-by: Elitsa Marinovska --- .../Scoping/ScopedNuCacheTests.cs | 119 +++++++++++ .../Scoping/ScopedNuCacheTests.cs | 192 ------------------ 2 files changed, 119 insertions(+), 192 deletions(-) create mode 100644 tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedNuCacheTests.cs delete mode 100644 tests/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedNuCacheTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedNuCacheTests.cs new file mode 100644 index 0000000000..2bc3682548 --- /dev/null +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/ScopedNuCacheTests.cs @@ -0,0 +1,119 @@ +using System; +using Microsoft.AspNetCore.Http; +using Moq; +using NUnit.Framework; +using Umbraco.Cms.Core.DependencyInjection; +using Umbraco.Cms.Core.Events; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Notifications; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Sync; +using Umbraco.Cms.Core.Web; +using Umbraco.Cms.Infrastructure.DependencyInjection; +using Umbraco.Cms.Tests.Common; +using Umbraco.Cms.Tests.Common.Testing; +using Umbraco.Cms.Tests.Integration.Testing; +using Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping; +using Umbraco.Extensions; + +namespace Umbraco.Tests.Scoping +{ + [TestFixture] + [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] + public class ScopedNuCacheTests : UmbracoIntegrationTest + { + private IContentService ContentService => GetRequiredService(); + private Mock MockHttpContextAccessor { get; set; } = CreateMockHttpContextAccessor(); + private IUmbracoContextFactory UmbracoContextFactory => GetRequiredService(); + private IContentTypeService ContentTypeService => GetRequiredService(); + private IVariationContextAccessor VariationContextAccessor => GetRequiredService(); + + protected override void CustomTestSetup(IUmbracoBuilder builder) + { + NotificationHandler.PublishedContent = notification => { }; + builder.Services.AddUnique(); + builder.AddCoreNotifications(); + builder.AddNotificationHandler(); + builder.Services.AddUnique(); + builder.Services.AddUnique(MockHttpContextAccessor.Object); + builder.AddNuCache(); + } + + public class NotificationHandler : INotificationHandler + { + public void Handle(ContentPublishedNotification notification) => PublishedContent?.Invoke(notification); + + public static Action PublishedContent { get; set; } + } + + private static Mock CreateMockHttpContextAccessor() + { + var mockHttpContextAccessor = new Mock(); + var httpContext = new DefaultHttpContext(); + httpContext.Request.Scheme = "http"; + httpContext.Request.Host = new HostString("localhost"); + + mockHttpContextAccessor.SetupGet(x => x.HttpContext).Returns(httpContext); + return mockHttpContextAccessor; + } + + [TestCase(true)] + [TestCase(false)] + public void TestScope(bool complete) + { + var umbracoContext = UmbracoContextFactory.EnsureUmbracoContext().UmbracoContext; + + // create document type, document + var contentType = new ContentType(ShortStringHelper, -1) { Alias = "CustomDocument", Name = "Custom Document" }; + ContentTypeService.Save(contentType); + var item = new Content("name", -1, contentType); + + using (var scope = ScopeProvider.CreateScope()) + { + ContentService.SaveAndPublish(item); + scope.Complete(); + } + + // event handler + var evented = 0; + NotificationHandler.PublishedContent = notification => + { + evented++; + + var e = umbracoContext.Content.GetById(item.Id); + + // during events, due to LiveSnapshot, we see the changes + Assert.IsNotNull(e); + Assert.AreEqual("changed", e.Name(VariationContextAccessor)); + }; + + // been created + var x = umbracoContext.Content.GetById(item.Id); + Assert.IsNotNull(x); + Assert.AreEqual("name", x.Name(VariationContextAccessor)); + + using (var scope = ScopeProvider.CreateScope()) + { + item.Name = "changed"; + ContentService.SaveAndPublish(item); + + if (complete) + { + scope.Complete(); + } + } + + // only 1 event occuring because we are publishing twice for the same event for + // the same object and the scope deduplicates the events (uses the latest) + Assert.AreEqual(complete ? 1 : 0, evented); + + // after the scope, + // if completed, we see the changes + // else changes have been rolled back + x = umbracoContext.Content.GetById(item.Id); + Assert.IsNotNull(x); + Assert.AreEqual(complete ? "changed" : "name", x.Name(VariationContextAccessor)); + } + } +} diff --git a/tests/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs b/tests/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs deleted file mode 100644 index b1131d7787..0000000000 --- a/tests/Umbraco.Tests/Scoping/ScopedNuCacheTests.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Web.Routing; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using Moq; -using NUnit.Framework; -using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Cache; -using Umbraco.Cms.Core.Configuration.Models; -using Umbraco.Cms.Core.DependencyInjection; -using Umbraco.Cms.Core.Events; -using Umbraco.Cms.Core.Hosting; -using Umbraco.Cms.Core.Models; -using Umbraco.Cms.Core.Models.PublishedContent; -using Umbraco.Cms.Core.Notifications; -using Umbraco.Cms.Core.Persistence.Repositories; -using Umbraco.Cms.Core.PublishedCache; -using Umbraco.Cms.Core.Security; -using Umbraco.Cms.Core.Services; -using Umbraco.Cms.Core.Strings; -using Umbraco.Cms.Core.Sync; -using Umbraco.Cms.Core.Web; -using Umbraco.Cms.Infrastructure.PublishedCache; -using Umbraco.Cms.Infrastructure.PublishedCache.Persistence; -using Umbraco.Cms.Tests.Common; -using Umbraco.Cms.Tests.Common.Testing; -using Umbraco.Extensions; -using Umbraco.Tests.TestHelpers; -using Umbraco.Web; -using Umbraco.Web.Composing; - -namespace Umbraco.Tests.Scoping -{ - [TestFixture] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, PublishedRepositoryEvents = true)] - public class ScopedNuCacheTests : TestWithDatabaseBase - { - private DistributedCacheBinder _distributedCacheBinder; - - protected override void Compose() - { - base.Compose(); - - // the cache refresher component needs to trigger to refresh caches - // but then, it requires a lot of plumbing ;( - // FIXME: and we cannot inject a DistributedCache yet - // so doing all this mess - Builder.Services.AddUnique(); - Builder.Services.AddUnique(f => Mock.Of()); - Builder.WithCollectionBuilder() - .Add(() => Builder.TypeLoader.GetCacheRefreshers()); - Builder.AddNotificationHandler(); - } - - public class NotificationHandler : INotificationHandler - { - public void Handle(ContentPublishedNotification notification) => PublishedContent?.Invoke(notification); - - public static Action PublishedContent { get; set; } - } - - public override void TearDown() - { - base.TearDown(); - - NotificationHandler.PublishedContent = null; - } - - protected override IPublishedSnapshotService CreatePublishedSnapshotService(GlobalSettings globalSettings = null) - { - var options = new PublishedSnapshotServiceOptions { IgnoreLocalDb = true }; - var publishedSnapshotAccessor = new UmbracoContextPublishedSnapshotAccessor(Current.UmbracoContextAccessor); - var runtimeStateMock = new Mock(); - runtimeStateMock.Setup(x => x.Level).Returns(() => RuntimeLevel.Run); - - var contentTypeFactory = Factory.GetRequiredService(); - var documentRepository = Mock.Of(); - var mediaRepository = Mock.Of(); - var memberRepository = Mock.Of(); - var hostingEnvironment = TestHelper.GetHostingEnvironment(); - - var typeFinder = TestHelper.GetTypeFinder(); - - var nuCacheSettings = new NuCacheSettings(); - var lifetime = new Mock(); - var repository = new NuCacheContentRepository(ScopeProvider, AppCaches.Disabled, Mock.Of>(), memberRepository, documentRepository, mediaRepository, Mock.Of(), new UrlSegmentProviderCollection(new[] { new DefaultUrlSegmentProvider(ShortStringHelper) })); - var snapshotService = new PublishedSnapshotService( - options, - null, - ServiceContext, - contentTypeFactory, - publishedSnapshotAccessor, - Mock.Of(), - base.ProfilingLogger, - NullLoggerFactory.Instance, - ScopeProvider, - new NuCacheContentService(repository, ScopeProvider, NullLoggerFactory.Instance, Mock.Of()), - DefaultCultureAccessor, - Microsoft.Extensions.Options.Options.Create(globalSettings ?? new GlobalSettings()), - Factory.GetRequiredService(), - new NoopPublishedModelFactory(), - hostingEnvironment, - Microsoft.Extensions.Options.Options.Create(nuCacheSettings)); - - return snapshotService; - } - - protected IUmbracoContext GetUmbracoContextNu(string url, RouteData routeData = null, bool setSingleton = false) - { - // ensure we have a PublishedSnapshotService - var service = PublishedSnapshotService as PublishedSnapshotService; - - var httpContext = GetHttpContextFactory(url, routeData).HttpContext; - var httpContextAccessor = TestHelper.GetHttpContextAccessor(httpContext); - var globalSettings = TestObjects.GetGlobalSettings(); - var umbracoContext = new UmbracoContext( - httpContextAccessor, - service, - Mock.Of(), - globalSettings, - HostingEnvironment, - new TestVariationContextAccessor(), - UriUtility, - new AspNetCookieManager(httpContextAccessor)); - - if (setSingleton) - Umbraco.Web.Composing.Current.UmbracoContextAccessor.UmbracoContext = umbracoContext; - - return umbracoContext; - } - - [TestCase(true)] - [TestCase(false)] - public void TestScope(bool complete) - { - var umbracoContext = GetUmbracoContextNu("http://example.com/", setSingleton: true); - - // wire cache refresher - _distributedCacheBinder = new DistributedCacheBinder(new DistributedCache(Current.ServerMessenger, Current.CacheRefreshers)); - - // create document type, document - var contentType = new ContentType(ShortStringHelper, -1) { Alias = "CustomDocument", Name = "Custom Document" }; - ServiceContext.ContentTypeService.Save(contentType); - var item = new Content("name", -1, contentType); - - // event handler - var evented = 0; - NotificationHandler.PublishedContent = notification => - { - evented++; - - var e = umbracoContext.Content.GetById(item.Id); - - // during events, due to LiveSnapshot, we see the changes - Assert.IsNotNull(e); - Assert.AreEqual("changed", e.Name(VariationContextAccessor)); - }; - - using (var scope = ScopeProvider.CreateScope()) - { - ServiceContext.ContentService.SaveAndPublish(item); - scope.Complete(); - } - - // been created - var x = umbracoContext.Content.GetById(item.Id); - Assert.IsNotNull(x); - Assert.AreEqual("name", x.Name(VariationContextAccessor)); - - using (var scope = ScopeProvider.CreateScope()) - { - item.Name = "changed"; - ServiceContext.ContentService.SaveAndPublish(item); - - if (complete) - scope.Complete(); - } - - // only 1 event occuring because we are publishing twice for the same event for - // the same object and the scope deduplicates the events (uses the latest) - Assert.AreEqual(complete ? 1 : 0, evented); - - // after the scope, - // if completed, we see the changes - // else changes have been rolled back - x = umbracoContext.Content.GetById(item.Id); - Assert.IsNotNull(x); - Assert.AreEqual(complete ? "changed" : "name", x.Name(VariationContextAccessor)); - } - } -}