diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs index dca465dc3..d1eed6b93 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/ContentQueryTests.cs @@ -12,6 +12,7 @@ using Squidex.ClientLibrary.Utils; using TestSuite.Model; #pragma warning disable SA1300 // Element should begin with upper-case letter +#pragma warning disable SA1507 // Code should not contain multiple blank lines in a row namespace TestSuite.ApiTests { diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/RuleRunnerTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/RuleRunnerTests.cs index bd1bac361..a46464cbe 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/RuleRunnerTests.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/RuleRunnerTests.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using Squidex.ClientLibrary; using Squidex.ClientLibrary.Management; using TestSuite.Fixtures; using TestSuite.Model; @@ -16,6 +17,7 @@ namespace TestSuite.ApiTests { public class RuleRunnerTests : IClassFixture, IClassFixture { + private readonly string secret = Guid.NewGuid().ToString(); private readonly string appName = Guid.NewGuid().ToString(); private readonly string schemaName = $"schema-{Guid.NewGuid()}"; private readonly string contentString = Guid.NewGuid().ToString(); @@ -46,6 +48,7 @@ namespace TestSuite.ApiTests { Action = new WebhookRuleActionDto { + SharedSecret = secret, Method = WebhookMethod.POST, Payload = null, PayloadType = null, @@ -65,8 +68,11 @@ namespace TestSuite.ApiTests // Get requests. var requests = await webhookCatcher.WaitForRequestsAsync(sessionId, TimeSpan.FromMinutes(2)); + var request = requests.FirstOrDefault(x => x.Method == "POST" && x.Content.Contains(schemaName, StringComparison.OrdinalIgnoreCase)); - Assert.Contains(requests, x => x.Method == "POST" && x.Content.Contains(schemaName, StringComparison.OrdinalIgnoreCase)); + Assert.NotNull(request); + Assert.NotNull(request.Headers["X-Signature"]); + Assert.Equal(request.Headers["X-Signature"], WebhookUtils.CalculateSignature(request.Content, secret)); // STEP 4: Get events @@ -93,6 +99,7 @@ namespace TestSuite.ApiTests { Action = new WebhookRuleActionDto { + SharedSecret = secret, Method = WebhookMethod.POST, Payload = null, PayloadType = null, @@ -109,8 +116,11 @@ namespace TestSuite.ApiTests // Get requests. var requests = await webhookCatcher.WaitForRequestsAsync(sessionId, TimeSpan.FromMinutes(2)); + var request = requests.FirstOrDefault(x => x.Method == "POST" && x.Content.Contains("logo-squared", StringComparison.OrdinalIgnoreCase)); - Assert.Contains(requests, x => x.Method == "POST" && x.Content.Contains("logo-squared", StringComparison.OrdinalIgnoreCase)); + Assert.NotNull(request); + Assert.NotNull(request.Headers["X-Signature"]); + Assert.Equal(request.Headers["X-Signature"], WebhookUtils.CalculateSignature(request.Content, secret)); // STEP 4: Get events @@ -137,6 +147,7 @@ namespace TestSuite.ApiTests { Action = new WebhookRuleActionDto { + SharedSecret = secret, Method = WebhookMethod.POST, Payload = null, PayloadType = null, @@ -153,8 +164,11 @@ namespace TestSuite.ApiTests // Get requests. var requests = await webhookCatcher.WaitForRequestsAsync(sessionId, TimeSpan.FromMinutes(2)); + var request = requests.FirstOrDefault(x => x.Method == "POST" && x.Content.Contains(schemaName, StringComparison.OrdinalIgnoreCase)); - Assert.Contains(requests, x => x.Method == "POST" && x.Content.Contains(schemaName, StringComparison.OrdinalIgnoreCase)); + Assert.NotNull(request); + Assert.NotNull(request.Headers["X-Signature"]); + Assert.Equal(request.Headers["X-Signature"], WebhookUtils.CalculateSignature(request.Content, secret)); // STEP 4: Get events @@ -181,6 +195,7 @@ namespace TestSuite.ApiTests { Action = new WebhookRuleActionDto { + SharedSecret = secret, Method = WebhookMethod.POST, Payload = null, PayloadType = null, @@ -197,8 +212,11 @@ namespace TestSuite.ApiTests // Get requests. var requests = await webhookCatcher.WaitForRequestsAsync(sessionId, TimeSpan.FromSeconds(30)); + var request = requests.FirstOrDefault(x => x.Method == "POST"); - Assert.Contains(requests, x => x.Method == "POST"); + Assert.NotNull(request); + Assert.NotNull(request.Headers["X-Signature"]); + Assert.Equal(request.Headers["X-Signature"], WebhookUtils.CalculateSignature(request.Content, secret)); // STEP 4: Get events diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj b/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj index e5abd3db4..3b5c30ccf 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj +++ b/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj @@ -22,7 +22,7 @@ - + diff --git a/backend/tools/TestSuite/TestSuite.Shared/ClientExtensions.cs b/backend/tools/TestSuite/TestSuite.Shared/ClientExtensions.cs index 42abe6639..45310792c 100644 --- a/backend/tools/TestSuite/TestSuite.Shared/ClientExtensions.cs +++ b/backend/tools/TestSuite/TestSuite.Shared/ClientExtensions.cs @@ -5,6 +5,8 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System.Security.Cryptography; +using System.Text; using Squidex.ClientLibrary; using Squidex.ClientLibrary.Management; using TestSuite.Fixtures; @@ -92,7 +94,7 @@ namespace TestSuite return new List(); } - public static async Task> WaitForHistoryAsync(this IHistoryClient assetsClient, string app, string channel, + public static async Task> WaitForHistoryAsync(this IHistoryClient historyClient, string app, string channel, Func predicate, TimeSpan timeout) { try @@ -101,7 +103,7 @@ namespace TestSuite while (!cts.IsCancellationRequested) { - var result = await assetsClient.GetHistoryAsync(app, channel, cts.Token); + var result = await historyClient.GetAppHistoryAsync(app, channel, cts.Token); if (result.Any(predicate)) { diff --git a/backend/tools/TestSuite/TestSuite.Shared/Fixtures/WebhookCatcherClient.cs b/backend/tools/TestSuite/TestSuite.Shared/Fixtures/WebhookCatcherClient.cs index 53e0e48a4..2e33d1ae7 100644 --- a/backend/tools/TestSuite/TestSuite.Shared/Fixtures/WebhookCatcherClient.cs +++ b/backend/tools/TestSuite/TestSuite.Shared/Fixtures/WebhookCatcherClient.cs @@ -28,6 +28,21 @@ namespace TestSuite.Fixtures [JsonPropertyName("content_base64")] public string Content { get; set; } + + [JsonIgnore] + public Dictionary Headers { get; set; } = new Dictionary(); + + [JsonPropertyName("headers")] + public WebhookHeader[] HeaderValues { get; set; } + } + + public sealed class WebhookHeader + { + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("value")] + public string Value { get; set; } } public sealed class WebhookCatcherClient @@ -82,6 +97,14 @@ namespace TestSuite.Fixtures { request.Content = Encoding.Default.GetString(Convert.FromBase64String(request.Content)); } + + if (request.HeaderValues != null) + { + foreach (var header in request.HeaderValues) + { + request.Headers[header.Name] = header.Value; + } + } } return result; diff --git a/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj b/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj index 6c819d5e6..cb82770c0 100644 --- a/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj +++ b/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj @@ -16,7 +16,7 @@ - +