From dcae6924075bafe09bbe85ac6a662836a8e11653 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 12 Jul 2021 11:54:38 -0600 Subject: [PATCH] Fix typo, adds [CannotSuppressNotification] --- .../Events/IScopedNotificationPublisher.cs | 2 +- .../Events/ScopedNotificationPublisher.cs | 12 ++++++++---- .../CannotSuppressNotificationAttribute.cs | 9 +++++++++ .../ContentRefreshNotification.cs | 2 ++ .../Notifications/MediaRefreshNotification.cs | 1 + .../MemberRefreshNotification.cs | 1 + .../ScopedEntityRemoveNotification.cs | 1 + .../Services/SectionServiceTests.cs | 2 +- .../Scoping/SupressNotificationsTests.cs | 19 ++++++++++++++++--- 9 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 src/Umbraco.Core/Notifications/CannotSuppressNotificationAttribute.cs diff --git a/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs b/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs index 75fbf83860..8ac4f4312d 100644 --- a/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs +++ b/src/Umbraco.Core/Events/IScopedNotificationPublisher.cs @@ -13,7 +13,7 @@ namespace Umbraco.Cms.Core.Events /// Supresses all notifications from being added/created until the result object is disposed. /// /// - IDisposable Supress(); + IDisposable Suppress(); /// /// Publishes a cancelable notification to the notification subscribers diff --git a/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs b/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs index 6ea7ee5b6a..cf6260291b 100644 --- a/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs +++ b/src/Umbraco.Core/Events/ScopedNotificationPublisher.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Threading.Tasks; using Umbraco.Cms.Core.Notifications; @@ -28,7 +29,7 @@ namespace Umbraco.Cms.Core.Events throw new ArgumentNullException(nameof(notification)); } - if (_isSuppressed) + if (CanSuppress(notification) && _isSuppressed) { return false; } @@ -44,7 +45,7 @@ namespace Umbraco.Cms.Core.Events throw new ArgumentNullException(nameof(notification)); } - if (_isSuppressed) + if (CanSuppress(notification) && _isSuppressed) { return false; } @@ -60,7 +61,7 @@ namespace Umbraco.Cms.Core.Events throw new ArgumentNullException(nameof(notification)); } - if (_isSuppressed) + if (CanSuppress(notification) && _isSuppressed) { return; } @@ -86,7 +87,7 @@ namespace Umbraco.Cms.Core.Events } } - public IDisposable Supress() + public IDisposable Suppress() { lock(_locker) { @@ -98,6 +99,9 @@ namespace Umbraco.Cms.Core.Events } } + private bool CanSuppress(INotification notification) + => notification.GetType().GetCustomAttribute() == null; + private class Suppressor : IDisposable { private bool _disposedValue; diff --git a/src/Umbraco.Core/Notifications/CannotSuppressNotificationAttribute.cs b/src/Umbraco.Core/Notifications/CannotSuppressNotificationAttribute.cs new file mode 100644 index 0000000000..8279ae4caf --- /dev/null +++ b/src/Umbraco.Core/Notifications/CannotSuppressNotificationAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Umbraco.Cms.Core.Notifications +{ + [AttributeUsage(AttributeTargets.Class)] + internal sealed class CannotSuppressNotificationAttribute : Attribute + { + } +} diff --git a/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs b/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs index 6957da7f70..f2c81d3fac 100644 --- a/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs +++ b/src/Umbraco.Core/Notifications/ContentRefreshNotification.cs @@ -5,7 +5,9 @@ using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Notifications { + [Obsolete("This is only used for the internal cache and will change, use saved notifications instead")] + [CannotSuppressNotification] [EditorBrowsable(EditorBrowsableState.Never)] public class ContentRefreshNotification : EntityRefreshNotification { diff --git a/src/Umbraco.Core/Notifications/MediaRefreshNotification.cs b/src/Umbraco.Core/Notifications/MediaRefreshNotification.cs index 1c8b8b9bea..4fe0f82d33 100644 --- a/src/Umbraco.Core/Notifications/MediaRefreshNotification.cs +++ b/src/Umbraco.Core/Notifications/MediaRefreshNotification.cs @@ -5,6 +5,7 @@ using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Notifications { + [CannotSuppressNotification] [Obsolete("This is only used for the internal cache and will change, use tree change notifications instead")] [EditorBrowsable(EditorBrowsableState.Never)] public class MediaRefreshNotification : EntityRefreshNotification diff --git a/src/Umbraco.Core/Notifications/MemberRefreshNotification.cs b/src/Umbraco.Core/Notifications/MemberRefreshNotification.cs index a22c48348f..d4dfeef68f 100644 --- a/src/Umbraco.Core/Notifications/MemberRefreshNotification.cs +++ b/src/Umbraco.Core/Notifications/MemberRefreshNotification.cs @@ -5,6 +5,7 @@ using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Notifications { + [CannotSuppressNotification] [Obsolete("This is only used for the internal cache and will change, use tree change notifications instead")] [EditorBrowsable(EditorBrowsableState.Never)] public class MemberRefreshNotification : EntityRefreshNotification diff --git a/src/Umbraco.Core/Notifications/ScopedEntityRemoveNotification.cs b/src/Umbraco.Core/Notifications/ScopedEntityRemoveNotification.cs index 307ae2103c..a86ea659bb 100644 --- a/src/Umbraco.Core/Notifications/ScopedEntityRemoveNotification.cs +++ b/src/Umbraco.Core/Notifications/ScopedEntityRemoveNotification.cs @@ -5,6 +5,7 @@ using Umbraco.Cms.Core.Models; namespace Umbraco.Cms.Core.Notifications { + [CannotSuppressNotification] [Obsolete("This is only used for the internal cache and will change, use tree change notifications instead")] [EditorBrowsable(EditorBrowsableState.Never)] public class ScopedEntityRemoveNotification : ObjectNotification diff --git a/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs index 1e9a80faf6..d1f25a8f82 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Core/Services/SectionServiceTests.cs @@ -42,7 +42,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Core.Services private IUser CreateTestUser() { using IScope scope = ScopeProvider.CreateScope(autoComplete: true); - using IDisposable _ = scope.Notifications.Supress(); + using IDisposable _ = scope.Notifications.Suppress(); var globalSettings = new GlobalSettings(); var user = new User(globalSettings) diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs index 4c3fa23504..c40249b886 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Scoping/SupressNotificationsTests.cs @@ -37,7 +37,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping public void GivenScope_WhenNotificationsSuppressed_ThenNotificationsDoNotExecute() { using IScope scope = ScopeProvider.CreateScope(autoComplete: true); - using IDisposable _ = scope.Notifications.Supress(); + using IDisposable _ = scope.Notifications.Suppress(); ContentType contentType = ContentTypeBuilder.CreateBasicContentType(); ContentTypeService.Save(contentType); @@ -50,7 +50,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping { using (IScope parentScope = ScopeProvider.CreateScope(autoComplete: true)) { - using IDisposable _ = parentScope.Notifications.Supress(); + using IDisposable _ = parentScope.Notifications.Suppress(); using (IScope childScope = ScopeProvider.CreateScope(autoComplete: true)) { @@ -68,7 +68,7 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping int asserted = 0; using (IScope scope = ScopeProvider.CreateScope(autoComplete: true)) { - using IDisposable suppressed = scope.Notifications.Supress(); + using IDisposable suppressed = scope.Notifications.Suppress(); MediaType mediaType = MediaTypeBuilder.CreateImageMediaType("test"); MediaTypeService.Save(mediaType); @@ -83,6 +83,19 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Scoping Assert.AreEqual(asserted + 1, TestContext.CurrentContext.AssertCount); } + [Test] + public void GivenSuppressedNotificationsOnParent_WhenChildSupresses_ThenExceptionIsThrown() + { + using (IScope parentScope = ScopeProvider.CreateScope(autoComplete: true)) + using (IDisposable parentSuppressed = parentScope.Notifications.Suppress()) + { + using (IScope childScope = ScopeProvider.CreateScope(autoComplete: true)) + { + Assert.Throws(() => childScope.Notifications.Suppress()); + } + } + } + private class TestContentNotificationHandler : INotificationHandler { public void Handle(ContentSavingNotification notification)