diff --git a/src/Umbraco.Core/Constants-WebhookEvents.cs b/src/Umbraco.Core/Constants-WebhookEvents.cs index 24fe890221..afd57b5188 100644 --- a/src/Umbraco.Core/Constants-WebhookEvents.cs +++ b/src/Umbraco.Core/Constants-WebhookEvents.cs @@ -4,29 +4,55 @@ public static partial class Constants { public static class WebhookEvents { - /// - /// Webhook event name for content publish. - /// - public const string ContentPublish = "ContentPublish"; + public static class Aliases + { + /// + /// Webhook event alias for content publish. + /// + public const string ContentPublish = "Umbraco.ContentPublish"; - /// - /// Webhook event name for content delete. - /// - public const string ContentDelete = "ContentDelete"; + /// + /// Webhook event alias for content delete. + /// + public const string ContentDelete = "Umbraco.ContentDelete"; - /// - /// Webhook event name for content unpublish. - /// - public const string ContentUnpublish = "ContentUnpublish"; + /// + /// Webhook event alias for content unpublish. + /// + public const string ContentUnpublish = "Umbraco.ContentUnpublish"; - /// - /// Webhook event name for media delete. - /// - public const string MediaDelete = "MediaDelete"; + /// + /// Webhook event alias for media delete. + /// + public const string MediaDelete = "Umbraco.MediaDelete"; - /// - /// Webhook event name for media save. - /// - public const string MediaSave = "MediaSave"; + /// + /// Webhook event alias for media save. + /// + public const string MediaSave = "Umbraco.MediaSave"; + } + + public static class Types + { + /// + /// Webhook event type for content. + /// + public const string Content = "Content"; + + /// + /// Webhook event type for content media. + /// + public const string Media = "Media"; + + /// + /// Webhook event type for content member. + /// + public const string Member = "Member"; + + /// + /// Webhook event type for others, this is the default category if you have not chosen one. + /// + public const string Other = "Other"; + } } } diff --git a/src/Umbraco.Core/Models/WebhookLog.cs b/src/Umbraco.Core/Models/WebhookLog.cs index bd37d79165..e65abdf990 100644 --- a/src/Umbraco.Core/Models/WebhookLog.cs +++ b/src/Umbraco.Core/Models/WebhookLog.cs @@ -14,7 +14,7 @@ public class WebhookLog public DateTime Date { get; set; } - public string EventName { get; set; } = string.Empty; + public string EventAlias { get; set; } = string.Empty; public int RetryCount { get; set; } diff --git a/src/Umbraco.Core/Persistence/Repositories/IWebhookRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IWebhookRepository.cs index d045cd172f..3013ee59e0 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IWebhookRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IWebhookRepository.cs @@ -29,9 +29,11 @@ public interface IWebhookRepository /// /// Gets a webhook by key /// - /// The key of the webhook which will be retrieved. - /// The webhook with the given key. - Task> GetByEventNameAsync(string eventName); + /// The alias of an event, which is referenced by a webhook. + /// + /// A paged model of + /// + Task> GetByAliasAsync(string alias); /// /// Gets a webhook by key diff --git a/src/Umbraco.Core/Services/IWebHookService.cs b/src/Umbraco.Core/Services/IWebHookService.cs index 84e5319fe1..785f5e8701 100644 --- a/src/Umbraco.Core/Services/IWebHookService.cs +++ b/src/Umbraco.Core/Services/IWebHookService.cs @@ -36,5 +36,5 @@ public interface IWebHookService /// /// Gets webhooks by event name. /// - Task> GetByEventNameAsync(string eventName); + Task> GetByAliasAsync(string alias); } diff --git a/src/Umbraco.Core/Services/IWebhookFiringService.cs b/src/Umbraco.Core/Services/IWebhookFiringService.cs index 0482290c3d..53a631bff3 100644 --- a/src/Umbraco.Core/Services/IWebhookFiringService.cs +++ b/src/Umbraco.Core/Services/IWebhookFiringService.cs @@ -4,5 +4,5 @@ namespace Umbraco.Cms.Core.Services; public interface IWebhookFiringService { - Task FireAsync(Webhook webhook, string eventName, object? payload, CancellationToken cancellationToken); + Task FireAsync(Webhook webhook, string eventAlias, object? payload, CancellationToken cancellationToken); } diff --git a/src/Umbraco.Core/Services/IWebhookLogFactory.cs b/src/Umbraco.Core/Services/IWebhookLogFactory.cs index fa600dda82..3f586f5da4 100644 --- a/src/Umbraco.Core/Services/IWebhookLogFactory.cs +++ b/src/Umbraco.Core/Services/IWebhookLogFactory.cs @@ -5,5 +5,5 @@ namespace Umbraco.Cms.Core.Services; public interface IWebhookLogFactory { - Task CreateAsync(string eventName, WebhookResponseModel responseModel, Webhook webhook, CancellationToken cancellationToken); + Task CreateAsync(string eventAlias, WebhookResponseModel responseModel, Webhook webhook, CancellationToken cancellationToken); } diff --git a/src/Umbraco.Core/Services/WebhookLogFactory.cs b/src/Umbraco.Core/Services/WebhookLogFactory.cs index 22dd75fe84..455bc45e27 100644 --- a/src/Umbraco.Core/Services/WebhookLogFactory.cs +++ b/src/Umbraco.Core/Services/WebhookLogFactory.cs @@ -5,12 +5,12 @@ namespace Umbraco.Cms.Core.Services; public class WebhookLogFactory : IWebhookLogFactory { - public async Task CreateAsync(string eventName, WebhookResponseModel responseModel, Webhook webhook, CancellationToken cancellationToken) + public async Task CreateAsync(string eventAlias, WebhookResponseModel responseModel, Webhook webhook, CancellationToken cancellationToken) { var log = new WebhookLog { Date = DateTime.UtcNow, - EventName = eventName, + EventAlias = eventAlias, Key = Guid.NewGuid(), Url = webhook.Url, WebhookKey = webhook.Key, diff --git a/src/Umbraco.Core/Services/WebhookService.cs b/src/Umbraco.Core/Services/WebhookService.cs index 9813199db8..424f1afb14 100644 --- a/src/Umbraco.Core/Services/WebhookService.cs +++ b/src/Umbraco.Core/Services/WebhookService.cs @@ -80,10 +80,10 @@ public class WebhookService : IWebHookService } /// - public async Task> GetByEventNameAsync(string eventName) + public async Task> GetByAliasAsync(string alias) { using ICoreScope scope = _provider.CreateCoreScope(); - PagedModel webhooks = await _webhookRepository.GetByEventNameAsync(eventName); + PagedModel webhooks = await _webhookRepository.GetByAliasAsync(alias); scope.Complete(); return webhooks.Items; diff --git a/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs index 52b8d233e5..d8386b9914 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/ContentDeleteWebhookEvent.cs @@ -7,6 +7,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; +[WebhookEvent("Content was deleted", Constants.WebhookEvents.Types.Content)] public class ContentDeleteWebhookEvent : WebhookEventContentBase { public ContentDeleteWebhookEvent( @@ -18,11 +19,12 @@ public class ContentDeleteWebhookEvent : WebhookEventContentBase Constants.WebhookEvents.Aliases.ContentUnpublish; + protected override IEnumerable GetEntitiesFromNotification(ContentDeletedNotification notification) => notification.DeletedEntities; diff --git a/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs index 8f308432b8..03f2e71706 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/ContentPublishWebhookEvent.cs @@ -10,6 +10,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; +[WebhookEvent("Content was published", Constants.WebhookEvents.Types.Content)] public class ContentPublishWebhookEvent : WebhookEventContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; @@ -26,13 +27,14 @@ public class ContentPublishWebhookEvent : WebhookEventContentBase Constants.WebhookEvents.Aliases.ContentPublish; + protected override IEnumerable GetEntitiesFromNotification(ContentPublishedNotification notification) => notification.PublishedEntities; protected override object? ConvertEntityToRequestPayload(IContent entity) diff --git a/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs index c8a8fd789e..354cdb295b 100644 --- a/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/ContentUnpublishWebhookEvent.cs @@ -7,6 +7,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; +[WebhookEvent("Content was unpublished", Constants.WebhookEvents.Types.Content)] public class ContentUnpublishWebhookEvent : WebhookEventContentBase { public ContentUnpublishWebhookEvent( @@ -18,11 +19,12 @@ public class ContentUnpublishWebhookEvent : WebhookEventContentBase Constants.WebhookEvents.Aliases.ContentDelete; + protected override IEnumerable GetEntitiesFromNotification(ContentUnpublishedNotification notification) => notification.UnpublishedEntities; protected override object ConvertEntityToRequestPayload(IContent entity) => new DefaultPayloadModel { Id = entity.Key }; diff --git a/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs index eb19e3e888..ab0fd98942 100644 --- a/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/MediaDeleteWebhookEvent.cs @@ -7,6 +7,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; +[WebhookEvent("Media was deleted", Constants.WebhookEvents.Types.Media)] public class MediaDeleteWebhookEvent : WebhookEventContentBase { public MediaDeleteWebhookEvent( @@ -18,11 +19,12 @@ public class MediaDeleteWebhookEvent : WebhookEventContentBase Constants.WebhookEvents.Aliases.MediaDelete; + protected override IEnumerable GetEntitiesFromNotification(MediaDeletedNotification notification) => notification.DeletedEntities; protected override object ConvertEntityToRequestPayload(IMedia entity) => new DefaultPayloadModel { Id = entity.Key }; diff --git a/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs b/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs index 9a7dcaa3d5..6907067b87 100644 --- a/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/Events/MediaSaveWebhookEvent.cs @@ -10,6 +10,7 @@ using Umbraco.Cms.Core.Sync; namespace Umbraco.Cms.Core.Webhooks.Events; +[WebhookEvent("Media was saved", Constants.WebhookEvents.Types.Media)] public class MediaSaveWebhookEvent : WebhookEventContentBase { private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor; @@ -26,13 +27,14 @@ public class MediaSaveWebhookEvent : WebhookEventContentBase Constants.WebhookEvents.Aliases.MediaSave; + protected override IEnumerable GetEntitiesFromNotification(MediaSavedNotification notification) => notification.SavedEntities; protected override object? ConvertEntityToRequestPayload(IMedia entity) diff --git a/src/Umbraco.Core/Webhooks/IWebhookEvent.cs b/src/Umbraco.Core/Webhooks/IWebhookEvent.cs index 954055d104..693cc22193 100644 --- a/src/Umbraco.Core/Webhooks/IWebhookEvent.cs +++ b/src/Umbraco.Core/Webhooks/IWebhookEvent.cs @@ -3,4 +3,8 @@ public interface IWebhookEvent { string EventName { get; } + + string EventType { get; } + + string Alias { get; } } diff --git a/src/Umbraco.Core/Webhooks/WebhookEventAttribute.cs b/src/Umbraco.Core/Webhooks/WebhookEventAttribute.cs new file mode 100644 index 0000000000..3c9015e8bf --- /dev/null +++ b/src/Umbraco.Core/Webhooks/WebhookEventAttribute.cs @@ -0,0 +1,26 @@ +namespace Umbraco.Cms.Core.Webhooks; + +[AttributeUsage(AttributeTargets.Class)] +public class WebhookEventAttribute : Attribute +{ + public WebhookEventAttribute(string name) + : this(name, Constants.WebhookEvents.Types.Other) + { + } + + public WebhookEventAttribute(string name, string eventType) + { + Name = name; + EventType = eventType; + } + + /// + /// Gets the friendly name of the event. + /// + public string? Name { get; } + + /// + /// Gets the type of event. + /// + public string? EventType { get; } +} diff --git a/src/Umbraco.Core/Webhooks/WebhookEventBase.cs b/src/Umbraco.Core/Webhooks/WebhookEventBase.cs index 8753eeecf9..cd1666135a 100644 --- a/src/Umbraco.Core/Webhooks/WebhookEventBase.cs +++ b/src/Umbraco.Core/Webhooks/WebhookEventBase.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Events; @@ -6,6 +6,7 @@ using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Sync; +using Umbraco.Extensions; namespace Umbraco.Cms.Core.Webhooks; @@ -14,26 +15,37 @@ public abstract class WebhookEventBase : IWebhookEvent, INotifica { private readonly IServerRoleAccessor _serverRoleAccessor; - /// + public abstract string Alias { get; } + public string EventName { get; set; } + public string EventType { get; } + protected IWebhookFiringService WebhookFiringService { get; } + protected IWebHookService WebHookService { get; } + protected WebhookSettings WebhookSettings { get; private set; } + + protected WebhookEventBase( IWebhookFiringService webhookFiringService, IWebHookService webHookService, IOptionsMonitor webhookSettings, - IServerRoleAccessor serverRoleAccessor, - string eventName) + IServerRoleAccessor serverRoleAccessor) { - EventName = eventName; WebhookFiringService = webhookFiringService; WebHookService = webHookService; _serverRoleAccessor = serverRoleAccessor; + // assign properties based on the attribute, if it is found + WebhookEventAttribute? attribute = GetType().GetCustomAttribute(false); + + EventType = attribute?.EventType ?? "Others"; + EventName = attribute?.Name ?? Alias; + WebhookSettings = webhookSettings.CurrentValue; webhookSettings.OnChange(x => WebhookSettings = x); } @@ -50,7 +62,7 @@ public abstract class WebhookEventBase : IWebhookEvent, INotifica continue; } - await WebhookFiringService.FireAsync(webhook, EventName, notification, cancellationToken); + await WebhookFiringService.FireAsync(webhook, Alias, notification, cancellationToken); } } @@ -79,7 +91,7 @@ public abstract class WebhookEventBase : IWebhookEvent, INotifica return; } - IEnumerable webhooks = await WebHookService.GetByEventNameAsync(EventName); + IEnumerable webhooks = await WebHookService.GetByAliasAsync(Alias); await ProcessWebhooks(notification, webhooks, cancellationToken); } diff --git a/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs b/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs index 5b8b8c626e..3f7cd4c7b2 100644 --- a/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs +++ b/src/Umbraco.Core/Webhooks/WebhookEventContentBase.cs @@ -16,9 +16,8 @@ public abstract class WebhookEventContentBase : WebhookE IWebhookFiringService webhookFiringService, IWebHookService webHookService, IOptionsMonitor webhookSettings, - IServerRoleAccessor serverRoleAccessor, - string eventName) - : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor, eventName) + IServerRoleAccessor serverRoleAccessor) + : base(webhookFiringService, webHookService, webhookSettings, serverRoleAccessor) { } @@ -38,7 +37,7 @@ public abstract class WebhookEventContentBase : WebhookE continue; } - await WebhookFiringService.FireAsync(webhook, EventName, ConvertEntityToRequestPayload(entity), cancellationToken); + await WebhookFiringService.FireAsync(webhook, Alias, ConvertEntityToRequestPayload(entity), cancellationToken); } } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index 306f7869f7..3a4e715228 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -97,5 +97,6 @@ public class UmbracoPlan : MigrationPlan // To 13.0.0 To("{C76D9C9A-635B-4D2C-A301-05642A523E9D}"); + To("{D5139400-E507-4259-A542-C67358F7E329}"); } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_13_0_0/RenameEventNameColumn.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_13_0_0/RenameEventNameColumn.cs new file mode 100644 index 0000000000..7a69a2441f --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_13_0_0/RenameEventNameColumn.cs @@ -0,0 +1,28 @@ +using Umbraco.Cms.Core; + +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_13_0_0; + +public class RenameEventNameColumn : MigrationBase +{ + public RenameEventNameColumn(IMigrationContext context) : base(context) + { + } + + protected override void Migrate() + { + // This check is here because we renamed a column from 13-rc1 to 13-rc2, the previous migration adds the table + // so if you are upgrading from 13-rc1 to 13-rc2 then this column will not exist. + // If you are however upgrading from 12, then this column will exist, and thus there is no need to rename it. + if (ColumnExists(Constants.DatabaseSchema.Tables.WebhookLog, "eventName") is false) + { + return; + } + + Rename + .Column("eventName") + .OnTable(Constants.DatabaseSchema.Tables.WebhookLog) + .To("eventAlias") + .Do(); + } + +} diff --git a/src/Umbraco.Infrastructure/Persistence/Dtos/WebhookLogDto.cs b/src/Umbraco.Infrastructure/Persistence/Dtos/WebhookLogDto.cs index a8606c7391..a9588ecb7d 100644 --- a/src/Umbraco.Infrastructure/Persistence/Dtos/WebhookLogDto.cs +++ b/src/Umbraco.Infrastructure/Persistence/Dtos/WebhookLogDto.cs @@ -33,9 +33,9 @@ internal class WebhookLogDto [NullSetting(NullSetting = NullSettings.NotNull)] public string Url { get; set; } = string.Empty; - [Column(Name = "eventName")] + [Column(Name = "eventAlias")] [NullSetting(NullSetting = NullSettings.NotNull)] - public string EventName { get; set; } = string.Empty; + public string EventAlias { get; set; } = string.Empty; [Column(Name = "retryCount")] [NullSetting(NullSetting = NullSettings.NotNull)] diff --git a/src/Umbraco.Infrastructure/Persistence/Factories/WebhookLogFactory.cs b/src/Umbraco.Infrastructure/Persistence/Factories/WebhookLogFactory.cs index 2cc6d5d55b..ff1378ed2d 100644 --- a/src/Umbraco.Infrastructure/Persistence/Factories/WebhookLogFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/Factories/WebhookLogFactory.cs @@ -10,7 +10,7 @@ internal static class WebhookLogFactory new() { Date = log.Date, - EventName = log.EventName, + EventAlias = log.EventAlias, RequestBody = log.RequestBody ?? string.Empty, ResponseBody = log.ResponseBody, RetryCount = log.RetryCount, @@ -27,7 +27,7 @@ internal static class WebhookLogFactory new() { Date = dto.Date, - EventName = dto.EventName, + EventAlias = dto.EventAlias, RequestBody = dto.RequestBody, ResponseBody = dto.ResponseBody, RetryCount = dto.RetryCount, diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/WebhookRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/WebhookRepository.cs index af6d651e44..b8fe5e52fe 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/WebhookRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/WebhookRepository.cs @@ -57,14 +57,14 @@ public class WebhookRepository : IWebhookRepository return webhookDto is null ? null : await DtoToEntity(webhookDto); } - public async Task> GetByEventNameAsync(string eventName) + public async Task> GetByAliasAsync(string alias) { Sql? sql = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql() .SelectAll() .From() .InnerJoin() .On(left => left.Id, right => right.WebhookId) - .Where(x => x.Event == eventName); + .Where(x => x.Event == alias); List? webhookDtos = await _scopeAccessor.AmbientScope?.Database.FetchAsync(sql)!; diff --git a/src/Umbraco.Infrastructure/Services/Implement/WebhookFiringService.cs b/src/Umbraco.Infrastructure/Services/Implement/WebhookFiringService.cs index cf09c0d3a2..67b55c913e 100644 --- a/src/Umbraco.Infrastructure/Services/Implement/WebhookFiringService.cs +++ b/src/Umbraco.Infrastructure/Services/Implement/WebhookFiringService.cs @@ -29,11 +29,11 @@ public class WebhookFiringService : IWebhookFiringService // TODO: Add queing instead of processing directly in thread // as this just makes save and publish longer - public async Task FireAsync(Webhook webhook, string eventName, object? payload, CancellationToken cancellationToken) + public async Task FireAsync(Webhook webhook, string eventAlias, object? payload, CancellationToken cancellationToken) { for (var retry = 0; retry < _webhookSettings.MaximumRetries; retry++) { - HttpResponseMessage response = await SendRequestAsync(webhook, eventName, payload, retry, cancellationToken); + HttpResponseMessage response = await SendRequestAsync(webhook, eventAlias, payload, retry, cancellationToken); if (response.IsSuccessStatusCode) { @@ -42,13 +42,13 @@ public class WebhookFiringService : IWebhookFiringService } } - private async Task SendRequestAsync(Webhook webhook, string eventName, object? payload, int retryCount, CancellationToken cancellationToken) + private async Task SendRequestAsync(Webhook webhook, string eventAlias, object? payload, int retryCount, CancellationToken cancellationToken) { using var httpClient = new HttpClient(); var serializedObject = _jsonSerializer.Serialize(payload); var stringContent = new StringContent(serializedObject, Encoding.UTF8, "application/json"); - stringContent.Headers.TryAddWithoutValidation("Umb-Webhook-Event", eventName); + stringContent.Headers.TryAddWithoutValidation("Umb-Webhook-Event", eventAlias); foreach (KeyValuePair header in webhook.Headers) { @@ -64,7 +64,7 @@ public class WebhookFiringService : IWebhookFiringService }; - WebhookLog log = await _webhookLogFactory.CreateAsync(eventName, webhookResponseModel, webhook, cancellationToken); + WebhookLog log = await _webhookLogFactory.CreateAsync(eventAlias, webhookResponseModel, webhook, cancellationToken); await _webhookLogService.CreateAsync(log); return response; diff --git a/src/Umbraco.Web.BackOffice/Controllers/WebhookController.cs b/src/Umbraco.Web.BackOffice/Controllers/WebhookController.cs index 9be5372ce5..49b80144a7 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/WebhookController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/WebhookController.cs @@ -4,6 +4,7 @@ using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Webhooks; +using Umbraco.Cms.Web.BackOffice.Services; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Models; @@ -16,13 +17,15 @@ public class WebhookController : UmbracoAuthorizedJsonController private readonly IUmbracoMapper _umbracoMapper; private readonly WebhookEventCollection _webhookEventCollection; private readonly IWebhookLogService _webhookLogService; + private readonly IWebhookPresentationFactory _webhookPresentationFactory; - public WebhookController(IWebHookService webHookService, IUmbracoMapper umbracoMapper, WebhookEventCollection webhookEventCollection, IWebhookLogService webhookLogService) + public WebhookController(IWebHookService webHookService, IUmbracoMapper umbracoMapper, WebhookEventCollection webhookEventCollection, IWebhookLogService webhookLogService, IWebhookPresentationFactory webhookPresentationFactory) { _webHookService = webHookService; _umbracoMapper = umbracoMapper; _webhookEventCollection = webhookEventCollection; _webhookLogService = webhookLogService; + _webhookPresentationFactory = webhookPresentationFactory; } [HttpGet] @@ -30,7 +33,7 @@ public class WebhookController : UmbracoAuthorizedJsonController { PagedModel webhooks = await _webHookService.GetAllAsync(skip, take); - List webhookViewModels = _umbracoMapper.MapEnumerable(webhooks.Items); + IEnumerable webhookViewModels = webhooks.Items.Select(_webhookPresentationFactory.Create); return Ok(webhookViewModels); } diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs index c973963495..dfa22b06e8 100644 --- a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilderExtensions.cs @@ -120,6 +120,7 @@ public static partial class UmbracoBuilderExtensions builder.Services.AddUnique(); builder.Services.AddSingleton(); builder.Services.AddTransient(); + builder.Services.AddUnique(); return builder; } diff --git a/src/Umbraco.Web.BackOffice/Mapping/WebhookMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/WebhookMapDefinition.cs index c797ce67ee..8d9982d0c6 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/WebhookMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/WebhookMapDefinition.cs @@ -10,7 +10,6 @@ public class WebhookMapDefinition : IMapDefinition public void DefineMaps(IUmbracoMapper mapper) { mapper.Define((_, _) => new Webhook(string.Empty), Map); - mapper.Define((_, _) => new WebhookViewModel(), Map); mapper.Define((_, _) => new WebhookEventViewModel(), Map); mapper.Define((_, _) => new WebhookLogViewModel(), Map); } @@ -19,7 +18,7 @@ public class WebhookMapDefinition : IMapDefinition private void Map(WebhookViewModel source, Webhook target, MapperContext context) { target.ContentTypeKeys = source.ContentTypeKeys; - target.Events = source.Events; + target.Events = source.Events.Select(x => x.Alias).ToArray(); target.Url = source.Url; target.Enabled = source.Enabled; target.Key = source.Key ?? Guid.NewGuid(); @@ -27,24 +26,18 @@ public class WebhookMapDefinition : IMapDefinition } // Umbraco.Code.MapAll - private void Map(Webhook source, WebhookViewModel target, MapperContext context) + private void Map(IWebhookEvent source, WebhookEventViewModel target, MapperContext context) { - target.ContentTypeKeys = source.ContentTypeKeys; - target.Events = source.Events; - target.Url = source.Url; - target.Enabled = source.Enabled; - target.Key = source.Key; - target.Headers = source.Headers; + target.EventName = source.EventName; + target.EventType = source.EventType; + target.Alias = source.Alias; } - // Umbraco.Code.MapAll - private void Map(IWebhookEvent source, WebhookEventViewModel target, MapperContext context) => target.EventName = source.EventName; - // Umbraco.Code.MapAll private void Map(WebhookLog source, WebhookLogViewModel target, MapperContext context) { target.Date = source.Date; - target.EventName = source.EventName; + target.EventAlias = source.EventAlias; target.Key = source.Key; target.RequestBody = source.RequestBody ?? string.Empty; target.ResponseBody = source.ResponseBody; diff --git a/src/Umbraco.Web.BackOffice/Services/IWebhookPresentationFactory.cs b/src/Umbraco.Web.BackOffice/Services/IWebhookPresentationFactory.cs new file mode 100644 index 0000000000..5d94607998 --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Services/IWebhookPresentationFactory.cs @@ -0,0 +1,10 @@ +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Web.Common.Models; + +namespace Umbraco.Cms.Web.BackOffice.Services; + +[Obsolete("Will be moved to a new namespace in V14")] +public interface IWebhookPresentationFactory +{ + WebhookViewModel Create(Webhook webhook); +} diff --git a/src/Umbraco.Web.BackOffice/Services/WebhookPresentationFactory.cs b/src/Umbraco.Web.BackOffice/Services/WebhookPresentationFactory.cs new file mode 100644 index 0000000000..57ef7e5f2a --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Services/WebhookPresentationFactory.cs @@ -0,0 +1,37 @@ +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Webhooks; +using Umbraco.Cms.Web.Common.Models; + +namespace Umbraco.Cms.Web.BackOffice.Services; + +internal class WebhookPresentationFactory : IWebhookPresentationFactory +{ + private readonly WebhookEventCollection _webhookEventCollection; + + public WebhookPresentationFactory(WebhookEventCollection webhookEventCollection) => _webhookEventCollection = webhookEventCollection; + + public WebhookViewModel Create(Webhook webhook) + { + var target = new WebhookViewModel + { + ContentTypeKeys = webhook.ContentTypeKeys, Events = webhook.Events.Select(Create).ToArray(), Url = webhook.Url, + Enabled = webhook.Enabled, + Key = webhook.Key, + Headers = webhook.Headers, + }; + + return target; + } + + private WebhookEventViewModel Create(string alias) + { + IWebhookEvent? webhookEvent = _webhookEventCollection.FirstOrDefault(x => x.Alias == alias); + return new WebhookEventViewModel + { + EventName = webhookEvent?.EventName ?? alias, + EventType = webhookEvent?.EventType ?? Constants.WebhookEvents.Types.Other, + Alias = alias, + }; + } +} diff --git a/src/Umbraco.Web.Common/Models/WebhookEventViewModel.cs b/src/Umbraco.Web.Common/Models/WebhookEventViewModel.cs index 441a367429..05243d4eb6 100644 --- a/src/Umbraco.Web.Common/Models/WebhookEventViewModel.cs +++ b/src/Umbraco.Web.Common/Models/WebhookEventViewModel.cs @@ -1,4 +1,5 @@ using System.Runtime.Serialization; +using Umbraco.Cms.Core.Webhooks; namespace Umbraco.Cms.Web.Common.Models; @@ -7,4 +8,10 @@ public class WebhookEventViewModel { [DataMember(Name = "eventName")] public string EventName { get; set; } = string.Empty; + + [DataMember(Name = "eventType")] + public string EventType { get; set; } = string.Empty; + + [DataMember(Name = "alias")] + public string Alias { get; set; } = string.Empty; } diff --git a/src/Umbraco.Web.Common/Models/WebhookLogViewModel.cs b/src/Umbraco.Web.Common/Models/WebhookLogViewModel.cs index f9bf6762f8..f63282b7cb 100644 --- a/src/Umbraco.Web.Common/Models/WebhookLogViewModel.cs +++ b/src/Umbraco.Web.Common/Models/WebhookLogViewModel.cs @@ -17,8 +17,8 @@ public class WebhookLogViewModel [DataMember(Name = "date")] public DateTime Date { get; set; } - [DataMember(Name = "eventName")] - public string EventName { get; set; } = string.Empty; + [DataMember(Name = "eventAlias")] + public string EventAlias { get; set; } = string.Empty; [DataMember(Name = "url")] public string Url { get; set; } = string.Empty; diff --git a/src/Umbraco.Web.Common/Models/WebhookViewModel.cs b/src/Umbraco.Web.Common/Models/WebhookViewModel.cs index a0efff398b..9030ff050c 100644 --- a/src/Umbraco.Web.Common/Models/WebhookViewModel.cs +++ b/src/Umbraco.Web.Common/Models/WebhookViewModel.cs @@ -12,7 +12,7 @@ public class WebhookViewModel public string Url { get; set; } = string.Empty; [DataMember(Name = "events")] - public string[] Events { get; set; } = Array.Empty(); + public WebhookEventViewModel[] Events { get; set; } = Array.Empty(); [DataMember(Name = "contentTypeKeys")] public Guid[] ContentTypeKeys { get; set; } = Array.Empty(); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.controller.js index 67bea3c07b..2e19a102a2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function LanguagePickerController($scope, languageResource, localizationService, webhooksResource) { + function EventPickerController($scope, languageResource, localizationService, webhooksResource) { var vm = this; @@ -38,10 +38,10 @@ .then((data) => { let selectedEvents = []; data.forEach(function (event) { - let eventObject = { name: event.eventName, selected: false} - vm.events.push(eventObject); - if($scope.model.selectedEvents && $scope.model.selectedEvents.includes(eventObject.name)){ - selectedEvents.push(eventObject); + event.selected = false; + vm.events.push(event); + if($scope.model.selectedEvents && $scope.model.selectedEvents.some(x => x.alias === event.alias)){ + selectedEvents.push(event); } }); @@ -55,19 +55,15 @@ if (!event.selected) { event.selected = true; $scope.model.selection.push(event); + // Only filter if we have not selected an item yet. if($scope.model.selection.length === 1){ - if(event.name.toLowerCase().includes("content")){ - vm.events = vm.events.filter(event => event.name.toLowerCase().includes("content")); - } - else if (event.name.toLowerCase().includes("media")){ - vm.events = vm.events.filter(event => event.name.toLowerCase().includes("media")); - } + vm.events = vm.events.filter(x => x.eventType === event.eventType); } - } else { - + } + else { $scope.model.selection.forEach(function (selectedEvent, index) { - if (selectedEvent.name === event.name) { + if (selectedEvent.alias === event.alias) { event.selected = false; $scope.model.selection.splice(index, 1); } @@ -75,6 +71,7 @@ if($scope.model.selection.length === 0){ vm.events = []; + $scope.model.selectedEvents = []; getAllEvents(); } } @@ -82,7 +79,6 @@ function submit(model) { if ($scope.model.submit) { - $scope.model.selection = $scope.model.selection.map((item) => item.name) $scope.model.submit(model); } } @@ -97,6 +93,6 @@ } - angular.module("umbraco").controller("Umbraco.Editors.EventPickerController", LanguagePickerController); + angular.module("umbraco").controller("Umbraco.Editors.EventPickerController", EventPickerController); })(); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html index d4033784ed..e65a5f767f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/eventpicker/eventpicker.html @@ -20,7 +20,7 @@ - {{ event.name }} + {{ event.eventName }} diff --git a/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html b/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html index 6c13daf764..f2db3096af 100644 --- a/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html +++ b/src/Umbraco.Web.UI.Client/src/views/webhooks/logs.html @@ -22,7 +22,7 @@ {{ log.webhookKey }} {{ log.date }} {{ log.url }} - {{ log.eventName }} + {{ log.eventAlias }} {{ log.retryCount }} diff --git a/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/details.html b/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/details.html index 3878c1ae87..d66c1463e7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/details.html +++ b/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/details.html @@ -22,7 +22,7 @@
Event -
{{model.log.eventName}}
+
{{model.log.eventAlias}}
Retry count diff --git a/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.controller.js index 9df465f738..6f8a17ceb8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.controller.js @@ -1,7 +1,7 @@ -(function () { +(function () { "use strict"; - function EditController($scope, editorService, contentTypeResource, mediaTypeResource) { + function EditController($scope, editorService, contentTypeResource, mediaTypeResource, memberTypeResource) { const vm = this; @@ -29,7 +29,7 @@ } function openContentTypePicker() { - const isContent = $scope.model.webhook ? $scope.model.webhook.events[0].toLowerCase().includes("content") : null; + const eventType = $scope.model.webhook ? $scope.model.webhook.events[0].eventType.toLowerCase() : null; const editor = { multiPicker: true, @@ -39,7 +39,7 @@ return item.nodeType === "container"; // || item.metaData.isElement || !!_.findWhere(vm.itemTypes, { udi: item.udi }); }, submit(model) { - getEntities(model.selection, isContent); + getEntities(model.selection, eventType); $scope.model.webhook.contentTypeKeys = model.selection.map(item => item.key); editorService.close(); }, @@ -48,9 +48,7 @@ } }; - const itemType = isContent ? "content" : "media"; - - switch (itemType) { + switch (eventType.toLowerCase()) { case "content": editorService.contentTypePicker(editor); break; @@ -82,8 +80,22 @@ }); } - function getEntities(selection, isContent) { - const resource = isContent ? contentTypeResource : mediaTypeResource; + function getEntities(selection, eventType) { + let resource; + switch (eventType.toCamelCase()) { + case "content": + resource = contentTypeResource; + break; + case "media": + resource = mediaTypeResource; + break; + case "member": + resource = memberTypeResource; + break; + default: + return; + } + $scope.model.contentTypes = []; selection.forEach(entity => { diff --git a/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.html b/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.html index cf55320f2f..4bc61fec98 100644 --- a/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/webhooks/overlays/edit.html @@ -42,9 +42,9 @@ { - vm.events = data.map(item => item.eventName); + vm.events = data; }); } function resolveEventNames(webhook) { webhook.events.forEach(event => { if (!vm.webhookEvents[webhook.key]) { - vm.webhookEvents[webhook.key] = event; + vm.webhookEvents[webhook.key] = event.eventName; } else { - vm.webhookEvents[webhook.key] += ", " + event; + vm.webhookEvents[webhook.key] += ", " + event.eventName; } }); } + function determineResource(resourceType){ + let resource; + switch (resourceType) { + case "content": + resource = contentTypeResource; + break; + case "media": + resource = mediaTypeResource; + break; + case "member": + resource = memberTypeResource; + break; + default: + return; + } + + return resource; + } + function getEntities(webhook) { - const isContent = webhook.events[0].toLowerCase().includes("content"); - const resource = isContent ? contentTypeResource : mediaTypeResource; + let resource = determineResource(webhook.events[0].eventType.toLowerCase()); let entities = []; webhook.contentTypeKeys.forEach(key => { @@ -68,8 +86,7 @@ } function resolveTypeNames(webhook) { - const isContent = webhook.events[0].toLowerCase().includes("content"); - const resource = isContent ? contentTypeResource : mediaTypeResource; + let resource = determineResource(webhook.events[0].eventType.toLowerCase()); if (vm.webHooksContentTypes[webhook.key]){ delete vm.webHooksContentTypes[webhook.key]; @@ -154,7 +171,7 @@ } function loadWebhooks(){ - webhooksResource + return webhooksResource .getAll() .then(result => { vm.webhooks = result; diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookLogServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookLogServiceTests.cs index af75becd1c..b4959de8e9 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookLogServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookLogServiceTests.cs @@ -21,7 +21,7 @@ public class WebhookLogServiceTests : UmbracoIntegrationTest var createdWebhookLog = await WebhookLogService.CreateAsync(new WebhookLog { Date = DateTime.UtcNow, - EventName = Constants.WebhookEvents.ContentPublish, + EventAlias = Constants.WebhookEvents.Aliases.ContentPublish, RequestBody = "Test Request Body", ResponseBody = "Test response body", StatusCode = "200", @@ -39,7 +39,7 @@ public class WebhookLogServiceTests : UmbracoIntegrationTest Assert.AreEqual(1, webhookLogsPaged.Items.Count()); var webHookLog = webhookLogsPaged.Items.First(); Assert.AreEqual(createdWebhookLog.Date.ToString(CultureInfo.InvariantCulture), webHookLog.Date.ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual(createdWebhookLog.EventName, webHookLog.EventName); + Assert.AreEqual(createdWebhookLog.EventAlias, webHookLog.EventAlias); Assert.AreEqual(createdWebhookLog.RequestBody, webHookLog.RequestBody); Assert.AreEqual(createdWebhookLog.ResponseBody, webHookLog.ResponseBody); Assert.AreEqual(createdWebhookLog.StatusCode, webHookLog.StatusCode); diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookServiceTests.cs index 6f6da74485..609388dfaf 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Services/WebhookServiceTests.cs @@ -14,11 +14,11 @@ public class WebhookServiceTests : UmbracoIntegrationTest private IWebHookService WebhookService => GetRequiredService(); [Test] - [TestCase("https://example.com", Constants.WebhookEvents.ContentPublish, "00000000-0000-0000-0000-010000000000")] - [TestCase("https://example.com", Constants.WebhookEvents.ContentDelete, "00000000-0000-0000-0000-000200000000")] - [TestCase("https://example.com", Constants.WebhookEvents.ContentUnpublish, "00000000-0000-0000-0000-300000000000")] - [TestCase("https://example.com", Constants.WebhookEvents.MediaDelete, "00000000-0000-0000-0000-000004000000")] - [TestCase("https://example.com", Constants.WebhookEvents.MediaSave, "00000000-0000-0000-0000-000000500000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.ContentPublish, "00000000-0000-0000-0000-010000000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.ContentDelete, "00000000-0000-0000-0000-000200000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.ContentUnpublish, "00000000-0000-0000-0000-300000000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.MediaDelete, "00000000-0000-0000-0000-000004000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.MediaSave, "00000000-0000-0000-0000-000000500000")] public async Task Can_Create_And_Get(string url, string webhookEvent, Guid key) { var createdWebhook = await WebhookService.CreateAsync(new Webhook(url, true, new[] { key }, new[] { webhookEvent })); @@ -37,9 +37,9 @@ public class WebhookServiceTests : UmbracoIntegrationTest [Test] public async Task Can_Get_All() { - var createdWebhookOne = await WebhookService.CreateAsync(new Webhook("https://example.com", true, new[] { Guid.NewGuid() }, new[] { Constants.WebhookEvents.ContentPublish })); - var createdWebhookTwo = await WebhookService.CreateAsync(new Webhook("https://example.com", true, new[] { Guid.NewGuid() }, new[] { Constants.WebhookEvents.ContentDelete })); - var createdWebhookThree = await WebhookService.CreateAsync(new Webhook("https://example.com", true, new[] { Guid.NewGuid() }, new[] { Constants.WebhookEvents.ContentUnpublish })); + var createdWebhookOne = await WebhookService.CreateAsync(new Webhook("https://example.com", true, new[] { Guid.NewGuid() }, new[] { Constants.WebhookEvents.Aliases.ContentPublish })); + var createdWebhookTwo = await WebhookService.CreateAsync(new Webhook("https://example.com", true, new[] { Guid.NewGuid() }, new[] { Constants.WebhookEvents.Aliases.ContentDelete })); + var createdWebhookThree = await WebhookService.CreateAsync(new Webhook("https://example.com", true, new[] { Guid.NewGuid() }, new[] { Constants.WebhookEvents.Aliases.ContentUnpublish })); var webhooks = await WebhookService.GetAllAsync(0, int.MaxValue); Assert.Multiple(() => @@ -52,11 +52,11 @@ public class WebhookServiceTests : UmbracoIntegrationTest } [Test] - [TestCase("https://example.com", Constants.WebhookEvents.ContentPublish, "00000000-0000-0000-0000-010000000000")] - [TestCase("https://example.com", Constants.WebhookEvents.ContentDelete, "00000000-0000-0000-0000-000200000000")] - [TestCase("https://example.com", Constants.WebhookEvents.ContentUnpublish, "00000000-0000-0000-0000-300000000000")] - [TestCase("https://example.com", Constants.WebhookEvents.MediaDelete, "00000000-0000-0000-0000-000004000000")] - [TestCase("https://example.com", Constants.WebhookEvents.MediaSave, "00000000-0000-0000-0000-000000500000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.ContentPublish, "00000000-0000-0000-0000-010000000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.ContentDelete, "00000000-0000-0000-0000-000200000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.ContentUnpublish, "00000000-0000-0000-0000-300000000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.MediaDelete, "00000000-0000-0000-0000-000004000000")] + [TestCase("https://example.com", Constants.WebhookEvents.Aliases.MediaSave, "00000000-0000-0000-0000-000000500000")] public async Task Can_Delete(string url, string webhookEvent, Guid key) { var createdWebhook = await WebhookService.CreateAsync(new Webhook(url, true, new[] { key }, new[] { webhookEvent })); @@ -71,7 +71,7 @@ public class WebhookServiceTests : UmbracoIntegrationTest [Test] public async Task Can_Create_With_No_EntityKeys() { - var createdWebhook = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.ContentPublish })); + var createdWebhook = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.Aliases.ContentPublish })); var webhook = await WebhookService.GetAsync(createdWebhook.Key); Assert.IsNotNull(webhook); @@ -81,24 +81,24 @@ public class WebhookServiceTests : UmbracoIntegrationTest [Test] public async Task Can_Update() { - var createdWebhook = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.ContentPublish })); - createdWebhook.Events = new[] { Constants.WebhookEvents.ContentDelete }; + var createdWebhook = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.Aliases.ContentPublish })); + createdWebhook.Events = new[] { Constants.WebhookEvents.Aliases.ContentDelete }; await WebhookService.UpdateAsync(createdWebhook); var updatedWebhook = await WebhookService.GetAsync(createdWebhook.Key); Assert.IsNotNull(updatedWebhook); Assert.AreEqual(1, updatedWebhook.Events.Length); - Assert.IsTrue(updatedWebhook.Events.Contains(Constants.WebhookEvents.ContentDelete)); + Assert.IsTrue(updatedWebhook.Events.Contains(Constants.WebhookEvents.Aliases.ContentDelete)); } [Test] public async Task Can_Get_By_EventName() { - var webhook1 = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.ContentPublish })); - var webhook2 = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.ContentUnpublish })); - var webhook3 = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.ContentUnpublish })); + var webhook1 = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.Aliases.ContentPublish })); + var webhook2 = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.Aliases.ContentUnpublish })); + var webhook3 = await WebhookService.CreateAsync(new Webhook("https://example.com", events: new[] { Constants.WebhookEvents.Aliases.ContentUnpublish })); - var result = await WebhookService.GetByEventNameAsync(Constants.WebhookEvents.ContentUnpublish); + var result = await WebhookService.GetByAliasAsync(Constants.WebhookEvents.Aliases.ContentUnpublish); Assert.IsNotEmpty(result); Assert.AreEqual(2, result.Count());