diff --git a/WireMock.Net Solution.sln.DotSettings b/WireMock.Net Solution.sln.DotSettings
index 79eca48e..c366605a 100644
--- a/WireMock.Net Solution.sln.DotSettings
+++ b/WireMock.Net Solution.sln.DotSettings
@@ -16,4 +16,6 @@
True
True
True
+ True
+ True
\ No newline at end of file
diff --git a/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs b/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
index b1d5274f..620e00d9 100644
--- a/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
+++ b/src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
@@ -57,5 +57,10 @@ namespace WireMock.Admin.Mappings
/// The Webhook.
///
public WebhookModel Webhook { get; set; }
+
+ ///
+ /// The Webhooks.
+ ///
+ public WebhookModel[] Webhooks { get; set; }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/IMapping.cs b/src/WireMock.Net/IMapping.cs
index 01e557f0..9d17844b 100644
--- a/src/WireMock.Net/IMapping.cs
+++ b/src/WireMock.Net/IMapping.cs
@@ -95,9 +95,9 @@ namespace WireMock
bool LogMapping { get; }
///
- /// The Webhook.
+ /// The Webhooks.
///
- IWebhook Webhook { get; }
+ IWebhook[] Webhooks { get; }
///
/// ProvideResponseAsync
diff --git a/src/WireMock.Net/Mapping.cs b/src/WireMock.Net/Mapping.cs
index f253b922..d9e15942 100644
--- a/src/WireMock.Net/Mapping.cs
+++ b/src/WireMock.Net/Mapping.cs
@@ -1,7 +1,6 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
-using WireMock.Admin.Mappings;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.ResponseProviders;
@@ -56,8 +55,8 @@ namespace WireMock
///
public bool LogMapping => !(Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider);
- ///
- public IWebhook Webhook { get; }
+ ///
+ public IWebhook[] Webhooks { get; }
///
/// Initializes a new instance of the class.
@@ -73,7 +72,7 @@ namespace WireMock
/// State in which the current mapping can occur. [Optional]
/// The next state which will occur after the current mapping execution. [Optional]
/// Only when the current state is executed this number, the next state which will occur. [Optional]
- /// The Webhook. [Optional]
+ /// The Webhooks. [Optional]
public Mapping(
Guid guid,
[CanBeNull] string title,
@@ -86,7 +85,7 @@ namespace WireMock
[CanBeNull] string executionConditionState,
[CanBeNull] string nextState,
[CanBeNull] int? stateTimes,
- [CanBeNull] IWebhook webhook)
+ [CanBeNull] IWebhook[] webhooks)
{
Guid = guid;
Title = title;
@@ -99,7 +98,7 @@ namespace WireMock
ExecutionConditionState = executionConditionState;
NextState = nextState;
StateTimes = stateTimes;
- Webhook = webhook;
+ Webhooks = webhooks;
}
///
diff --git a/src/WireMock.Net/Models/Webhook.cs b/src/WireMock.Net/Models/Webhook.cs
index b5583d24..7e2fef8b 100644
--- a/src/WireMock.Net/Models/Webhook.cs
+++ b/src/WireMock.Net/Models/Webhook.cs
@@ -1,8 +1,4 @@
-using System.Collections.Generic;
-using JetBrains.Annotations;
-using WireMock.Types;
-
-namespace WireMock.Models
+namespace WireMock.Models
{
///
/// Webhook
diff --git a/src/WireMock.Net/Owin/WireMockMiddleware.cs b/src/WireMock.Net/Owin/WireMockMiddleware.cs
index 3c49679a..8a9d8c9e 100644
--- a/src/WireMock.Net/Owin/WireMockMiddleware.cs
+++ b/src/WireMock.Net/Owin/WireMockMiddleware.cs
@@ -156,9 +156,9 @@ namespace WireMock.Owin
UpdateScenarioState(targetMapping);
}
- if (!targetMapping.IsAdminInterface && targetMapping.Webhook != null)
+ if (!targetMapping.IsAdminInterface && targetMapping.Webhooks?.Length > 0)
{
- await SendToWebhookAsync(targetMapping, request, response).ConfigureAwait(false);
+ await SendToWebhooksAsync(targetMapping, request, response).ConfigureAwait(false);
}
}
catch (Exception ex)
@@ -191,18 +191,21 @@ namespace WireMock.Owin
await CompletedTask;
}
- private async Task SendToWebhookAsync(IMapping mapping, RequestMessage request, ResponseMessage response)
+ private async Task SendToWebhooksAsync(IMapping mapping, RequestMessage request, ResponseMessage response)
{
- var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
- var webhookSender = new WebhookSender(mapping.Settings);
+ for (int index = 0; index < mapping.Webhooks.Length; index++)
+ {
+ var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
+ var webhookSender = new WebhookSender(mapping.Settings);
- try
- {
- await webhookSender.SendAsync(httpClientForWebhook, mapping.Webhook.Request, request, response).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _options.Logger.Error($"Sending message to Webhook Mapping '{mapping.Guid}' failed. Exception: {ex}");
+ try
+ {
+ await webhookSender.SendAsync(httpClientForWebhook, mapping.Webhooks[index].Request, request, response).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _options.Logger.Error($"Sending message to Webhook [{index}] from Mapping '{mapping.Guid}' failed. Exception: {ex}");
+ }
}
}
diff --git a/src/WireMock.Net/Serialization/MappingConverter.cs b/src/WireMock.Net/Serialization/MappingConverter.cs
index cc08c161..229d4ad4 100644
--- a/src/WireMock.Net/Serialization/MappingConverter.cs
+++ b/src/WireMock.Net/Serialization/MappingConverter.cs
@@ -84,10 +84,18 @@ namespace WireMock.Serialization
Response = new ResponseModel
{
Delay = (int?)response.Delay?.TotalMilliseconds
- },
- Webhook = WebhookMapper.Map(mapping.Webhook)
+ }
};
+ if (mapping.Webhooks?.Length == 1)
+ {
+ mappingModel.Webhook = WebhookMapper.Map(mapping.Webhooks[0]);
+ }
+ else if (mapping.Webhooks?.Length > 1)
+ {
+ mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
+ }
+
if (bodyMatcher?.Matchers != null)
{
mappingModel.Request.Body = new BodyModel();
diff --git a/src/WireMock.Net/Server/IRespondWithAProvider.cs b/src/WireMock.Net/Server/IRespondWithAProvider.cs
index 560b3562..f58d063f 100644
--- a/src/WireMock.Net/Server/IRespondWithAProvider.cs
+++ b/src/WireMock.Net/Server/IRespondWithAProvider.cs
@@ -103,14 +103,14 @@ namespace WireMock.Server
IRespondWithAProvider WillSetStateTo(int state, int? times = 1);
///
- /// Add a Webbook to call after the response has been generated.
+ /// Add (multiple) Webhook(s) to call after the response has been generated.
///
- /// The Webhook
+ /// The Webhooks
/// The .
- IRespondWithAProvider WithWebhook(IWebhook webhook);
+ IRespondWithAProvider WithWebhook(params IWebhook[] webhooks);
///
- /// Add a Webbook to call after the response has been generated.
+ /// Add a Webhook to call after the response has been generated.
///
/// The Webhook Url
/// The method to use. [optional]
@@ -129,7 +129,7 @@ namespace WireMock.Server
);
///
- /// Add a Webbook to call after the response has been generated.
+ /// Add a Webhook to call after the response has been generated.
///
/// The Webhook Url
/// The method to use. [optional]
diff --git a/src/WireMock.Net/Server/RespondWithAProvider.cs b/src/WireMock.Net/Server/RespondWithAProvider.cs
index 59837f8b..ca39634c 100644
--- a/src/WireMock.Net/Server/RespondWithAProvider.cs
+++ b/src/WireMock.Net/Server/RespondWithAProvider.cs
@@ -1,209 +1,212 @@
-// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
-// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
-using System;
+// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
+// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
+using System;
using System.Collections.Generic;
using JetBrains.Annotations;
-using WireMock.Matchers.Request;
-using WireMock.Models;
-using WireMock.ResponseProviders;
-using WireMock.Settings;
+using WireMock.Matchers.Request;
+using WireMock.Models;
+using WireMock.ResponseProviders;
+using WireMock.Settings;
using WireMock.Types;
using WireMock.Util;
+using WireMock.Validation;
+
+namespace WireMock.Server
+{
+ ///
+ /// The respond with a provider.
+ ///
+ internal class RespondWithAProvider : IRespondWithAProvider
+ {
+ private int _priority;
+ private string _title;
+ private string _path;
+ private string _executionConditionState;
+ private string _nextState;
+ private string _scenario;
+ private int _timesInSameState = 1;
+ private readonly RegistrationCallback _registrationCallback;
+ private readonly IRequestMatcher _requestMatcher;
+ private readonly IWireMockServerSettings _settings;
+ private readonly bool _saveToFile;
+
+ public Guid Guid { get; private set; } = Guid.NewGuid();
+
+ public IWebhook[] Webhooks { get; private set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The registration callback.
+ /// The request matcher.
+ /// The WireMockServerSettings.
+ /// Optional boolean to indicate if this mapping should be saved as static mapping file.
+ public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher, IWireMockServerSettings settings, bool saveToFile = false)
+ {
+ _registrationCallback = registrationCallback;
+ _requestMatcher = requestMatcher;
+ _settings = settings;
+ _saveToFile = saveToFile;
+ }
+
+ ///
+ /// The respond with.
+ ///
+ /// The provider.
+ public void RespondWith(IResponseProvider provider)
+ {
+ _registrationCallback(new Mapping(Guid, _title, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhooks), _saveToFile);
+ }
+
+ ///
+ public IRespondWithAProvider WithGuid(string guid)
+ {
+ return WithGuid(Guid.Parse(guid));
+ }
+
+ ///
+ public IRespondWithAProvider WithGuid(Guid guid)
+ {
+ Guid = guid;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider WithTitle(string title)
+ {
+ _title = title;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider WithPath(string path)
+ {
+ _path = path;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider AtPriority(int priority)
+ {
+ _priority = priority;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider InScenario(string scenario)
+ {
+ _scenario = scenario;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider InScenario(int scenario)
+ {
+ return InScenario(scenario.ToString());
+ }
+
+ ///
+ public IRespondWithAProvider WhenStateIs(string state)
+ {
+ if (string.IsNullOrEmpty(_scenario))
+ {
+ throw new NotSupportedException("Unable to set state condition when no scenario is defined.");
+ }
+
+ _executionConditionState = state;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider WhenStateIs(int state)
+ {
+ return WhenStateIs(state.ToString());
+ }
+
+ ///
+ public IRespondWithAProvider WillSetStateTo(string state, int? times = 1)
+ {
+ if (string.IsNullOrEmpty(_scenario))
+ {
+ throw new NotSupportedException("Unable to set next state when no scenario is defined.");
+ }
+
+ _nextState = state;
+ _timesInSameState = times ?? 1;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider WillSetStateTo(int state, int? times = 1)
+ {
+ return WillSetStateTo(state.ToString(), times);
+ }
+
+ ///
+ public IRespondWithAProvider WithWebhook(params IWebhook[] webhooks)
+ {
+ Check.HasNoNulls(webhooks, nameof(webhooks));
+
+ Webhooks = webhooks;
+
+ return this;
+ }
+
+ ///
+ public IRespondWithAProvider WithWebhook(
+ [NotNull] string url,
+ [CanBeNull] string method = "post",
+ [CanBeNull] IDictionary> headers = null,
+ [CanBeNull] string body = null,
+ bool useTransformer = true,
+ TransformerType transformerType = TransformerType.Handlebars)
+ {
+ Webhooks = new[] { InitWebhook(url, method, headers, useTransformer, transformerType) };
-namespace WireMock.Server
-{
- ///
- /// The respond with a provider.
- ///
- internal class RespondWithAProvider : IRespondWithAProvider
- {
- private int _priority;
- private string _title;
- private string _path;
- private string _executionConditionState;
- private string _nextState;
- private string _scenario;
- private int _timesInSameState = 1;
- private readonly RegistrationCallback _registrationCallback;
- private readonly IRequestMatcher _requestMatcher;
- private readonly IWireMockServerSettings _settings;
- private readonly bool _saveToFile;
-
- public Guid Guid { get; private set; } = Guid.NewGuid();
-
- public IWebhook Webhook { get; private set; }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The registration callback.
- /// The request matcher.
- /// The WireMockServerSettings.
- /// Optional boolean to indicate if this mapping should be saved as static mapping file.
- public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher, IWireMockServerSettings settings, bool saveToFile = false)
- {
- _registrationCallback = registrationCallback;
- _requestMatcher = requestMatcher;
- _settings = settings;
- _saveToFile = saveToFile;
- }
-
- ///
- /// The respond with.
- ///
- /// The provider.
- public void RespondWith(IResponseProvider provider)
- {
- _registrationCallback(new Mapping(Guid, _title, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhook), _saveToFile);
- }
-
- ///
- public IRespondWithAProvider WithGuid(string guid)
- {
- return WithGuid(Guid.Parse(guid));
- }
-
- ///
- public IRespondWithAProvider WithGuid(Guid guid)
- {
- Guid = guid;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider WithTitle(string title)
- {
- _title = title;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider WithPath(string path)
- {
- _path = path;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider AtPriority(int priority)
- {
- _priority = priority;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider InScenario(string scenario)
- {
- _scenario = scenario;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider InScenario(int scenario)
- {
- return InScenario(scenario.ToString());
- }
-
- ///
- public IRespondWithAProvider WhenStateIs(string state)
- {
- if (string.IsNullOrEmpty(_scenario))
- {
- throw new NotSupportedException("Unable to set state condition when no scenario is defined.");
- }
-
- _executionConditionState = state;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider WhenStateIs(int state)
- {
- return WhenStateIs(state.ToString());
- }
-
- ///
- public IRespondWithAProvider WillSetStateTo(string state, int? times = 1)
- {
- if (string.IsNullOrEmpty(_scenario))
- {
- throw new NotSupportedException("Unable to set next state when no scenario is defined.");
- }
-
- _nextState = state;
- _timesInSameState = times ?? 1;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider WillSetStateTo(int state, int? times = 1)
- {
- return WillSetStateTo(state.ToString(), times);
- }
-
- ///
- public IRespondWithAProvider WithWebhook(IWebhook webhook)
- {
- Webhook = webhook;
-
- return this;
- }
-
- ///
- public IRespondWithAProvider WithWebhook(
- [NotNull] string url,
- [CanBeNull] string method = "post",
- [CanBeNull] IDictionary> headers = null,
- [CanBeNull] string body = null,
- bool useTransformer = true,
- TransformerType transformerType = TransformerType.Handlebars)
- {
- Webhook = InitWebhook(url, method, headers, useTransformer, transformerType);
-
if (body != null)
{
- Webhook.Request.BodyData = new BodyData
+ Webhooks[0].Request.BodyData = new BodyData
{
BodyAsString = body,
DetectedBodyType = BodyType.String,
DetectedBodyTypeFromContentType = BodyType.String
};
- }
-
- return this;
+ }
+
+ return this;
}
- ///
- public IRespondWithAProvider WithWebhook(
- [NotNull] string url,
- [CanBeNull] string method = "post",
- [CanBeNull] IDictionary> headers = null,
- [CanBeNull] object body = null,
- bool useTransformer = true,
- TransformerType transformerType = TransformerType.Handlebars)
- {
- Webhook = InitWebhook(url, method, headers, useTransformer, transformerType);
-
+ ///
+ public IRespondWithAProvider WithWebhook(
+ [NotNull] string url,
+ [CanBeNull] string method = "post",
+ [CanBeNull] IDictionary> headers = null,
+ [CanBeNull] object body = null,
+ bool useTransformer = true,
+ TransformerType transformerType = TransformerType.Handlebars)
+ {
+ Webhooks = new[] { InitWebhook(url, method, headers, useTransformer, transformerType) };
+
if (body != null)
{
- Webhook.Request.BodyData = new BodyData
+ Webhooks[0].Request.BodyData = new BodyData
{
BodyAsJson = body,
DetectedBodyType = BodyType.Json,
DetectedBodyTypeFromContentType = BodyType.Json
};
- }
-
- return this;
- }
-
+ }
+
+ return this;
+ }
+
private IWebhook InitWebhook(
string url,
string method,
@@ -222,6 +225,6 @@ namespace WireMock.Server
TransformerType = transformerType
}
};
- }
- }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs
index 9087a4ed..b6970ad9 100644
--- a/src/WireMock.Net/Server/WireMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs
@@ -470,10 +470,15 @@ namespace WireMock.Server
respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo);
}
- if (mappingModel.Webhook?.Request != null)
+ if (mappingModel.Webhook != null)
{
respondProvider = respondProvider.WithWebhook(WebhookMapper.Map(mappingModel.Webhook));
}
+ else if (mappingModel.Webhooks?.Length > 1)
+ {
+ var webhooks = mappingModel.Webhooks.Select(WebhookMapper.Map).ToArray();
+ respondProvider = respondProvider.WithWebhook(webhooks);
+ }
respondProvider.RespondWith(responseBuilder);
diff --git a/test/WireMock.Net.Tests/Serialization/MappingConverterTests.cs b/test/WireMock.Net.Tests/Serialization/MappingConverterTests.cs
index c839c6f2..de2a4776 100644
--- a/test/WireMock.Net.Tests/Serialization/MappingConverterTests.cs
+++ b/test/WireMock.Net.Tests/Serialization/MappingConverterTests.cs
@@ -24,31 +24,34 @@ namespace WireMock.Net.Tests.Serialization
}
[Fact]
- public void ToMappingModel()
+ public void ToMappingModel_With_SingleWebHook()
{
// Assign
var request = Request.Create();
var response = Response.Create();
- var webhook = new Webhook
+ var webhooks = new IWebhook[]
{
- Request = new WebhookRequest
+ new Webhook
{
- Url = "https://test.com",
- Headers = new Dictionary>
+ Request = new WebhookRequest
{
- { "Single", new WireMockList("x") },
- { "Multi", new WireMockList("a", "b") }
- },
- Method = "post",
- BodyData = new BodyData
- {
- BodyAsString = "b",
- DetectedBodyType = BodyType.String,
- DetectedBodyTypeFromContentType = BodyType.String
+ Url = "https://test.com",
+ Headers = new Dictionary>
+ {
+ { "Single", new WireMockList("x") },
+ { "Multi", new WireMockList("a", "b") }
+ },
+ Method = "post",
+ BodyData = new BodyData
+ {
+ BodyAsString = "b",
+ DetectedBodyType = BodyType.String,
+ DetectedBodyTypeFromContentType = BodyType.String
+ }
}
}
};
- var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 0, null, null, null, null, webhook);
+ var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 0, null, null, null, null, webhooks);
// Act
var model = _sut.ToMappingModel(mapping);
@@ -61,6 +64,8 @@ namespace WireMock.Net.Tests.Serialization
model.Response.UseTransformer.Should().BeNull();
model.Response.Headers.Should().BeNull();
+ model.Webhooks.Should().BeNull();
+
model.Webhook.Request.Method.Should().Be("post");
model.Webhook.Request.Url.Should().Be("https://test.com");
model.Webhook.Request.Headers.Should().HaveCount(2);
@@ -68,6 +73,80 @@ namespace WireMock.Net.Tests.Serialization
model.Webhook.Request.BodyAsJson.Should().BeNull();
}
+ [Fact]
+ public void ToMappingModel_With_MultipleWebHooks()
+ {
+ // Assign
+ var request = Request.Create();
+ var response = Response.Create();
+ var webhooks = new IWebhook[]
+ {
+ new Webhook
+ {
+ Request = new WebhookRequest
+ {
+ Url = "https://test1.com",
+ Headers = new Dictionary>
+ {
+ { "One", new WireMockList("x") }
+ },
+ Method = "post",
+ BodyData = new BodyData
+ {
+ BodyAsString = "1",
+ DetectedBodyType = BodyType.String,
+ DetectedBodyTypeFromContentType = BodyType.String
+ }
+ }
+ },
+
+ new Webhook
+ {
+ Request = new WebhookRequest
+ {
+ Url = "https://test2.com",
+ Headers = new Dictionary>
+ {
+ { "First", new WireMockList("x") },
+ { "Second", new WireMockList("a", "b") }
+ },
+ Method = "post",
+ BodyData = new BodyData
+ {
+ BodyAsString = "2",
+ DetectedBodyType = BodyType.String,
+ DetectedBodyTypeFromContentType = BodyType.String
+ }
+ }
+ }
+ };
+ var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 0, null, null, null, null, webhooks
+);
+
+ // Act
+ var model = _sut.ToMappingModel(mapping);
+
+ // Assert
+ model.Should().NotBeNull();
+ model.Priority.Should().BeNull();
+
+ model.Response.BodyAsJsonIndented.Should().BeNull();
+ model.Response.UseTransformer.Should().BeNull();
+ model.Response.Headers.Should().BeNull();
+
+ model.Webhook.Should().BeNull();
+
+ model.Webhooks[0].Request.Method.Should().Be("post");
+ model.Webhooks[0].Request.Url.Should().Be("https://test1.com");
+ model.Webhooks[0].Request.Headers.Should().HaveCount(1);
+ model.Webhooks[0].Request.Body.Should().Be("1");
+
+ model.Webhooks[1].Request.Method.Should().Be("post");
+ model.Webhooks[1].Request.Url.Should().Be("https://test2.com");
+ model.Webhooks[1].Request.Headers.Should().HaveCount(2);
+ model.Webhooks[1].Request.Body.Should().Be("2");
+ }
+
[Fact]
public void ToMappingModel_WithPriority_ReturnsPriority()
{
diff --git a/test/WireMock.Net.Tests/WireMockServer.WebhookTests.cs b/test/WireMock.Net.Tests/WireMockServer.WebhookTests.cs
index 7e6ae43e..f988a4c4 100644
--- a/test/WireMock.Net.Tests/WireMockServer.WebhookTests.cs
+++ b/test/WireMock.Net.Tests/WireMockServer.WebhookTests.cs
@@ -16,6 +16,74 @@ namespace WireMock.Net.Tests
{
public class WireMockServerWebhookTests
{
+ [Fact]
+ public async Task WireMockServer_WithWebhooks_Should_Send_Message_To_Webhooks()
+ {
+ // Assign
+ var serverReceivingTheWebhook1 = WireMockServer.Start();
+ serverReceivingTheWebhook1.Given(Request.Create().UsingPost()).RespondWith(Response.Create().WithStatusCode(200));
+
+ var serverReceivingTheWebhook2 = WireMockServer.Start();
+ serverReceivingTheWebhook2.Given(Request.Create().UsingPost()).RespondWith(Response.Create().WithStatusCode(200));
+
+ var webhook1 = new Webhook
+ {
+ Request = new WebhookRequest
+ {
+ Url = serverReceivingTheWebhook1.Urls[0],
+ Method = "post",
+ BodyData = new BodyData
+ {
+ BodyAsString = "1",
+ DetectedBodyType = BodyType.String,
+ DetectedBodyTypeFromContentType = BodyType.String
+ }
+ }
+ };
+
+ var webhook2 = new Webhook
+ {
+ Request = new WebhookRequest
+ {
+ Url = serverReceivingTheWebhook2.Urls[0],
+ Method = "post",
+ BodyData = new BodyData
+ {
+ BodyAsString = "2",
+ DetectedBodyType = BodyType.String,
+ DetectedBodyTypeFromContentType = BodyType.String
+ }
+ }
+ };
+
+ // Act
+ var server = WireMockServer.Start();
+ server.Given(Request.Create().UsingPost())
+ .WithWebhook(webhook1, webhook2)
+ .RespondWith(Response.Create().WithBody("a-response"));
+
+ var request = new HttpRequestMessage
+ {
+ Method = HttpMethod.Post,
+ RequestUri = new Uri($"{server.Urls[0]}/TST"),
+ Content = new StringContent("test")
+ };
+
+ // Assert
+ var response = await new HttpClient().SendAsync(request);
+ string content = await response.Content.ReadAsStringAsync();
+
+ response.StatusCode.Should().Be(HttpStatusCode.OK);
+ content.Should().Be("a-response");
+
+ serverReceivingTheWebhook1.LogEntries.Should().HaveCount(1);
+ serverReceivingTheWebhook2.LogEntries.Should().HaveCount(1);
+
+ server.Dispose();
+ serverReceivingTheWebhook1.Dispose();
+ serverReceivingTheWebhook2.Dispose();
+ }
+
[Fact]
public async Task WireMockServer_WithWebhook_Should_Send_Message_To_Webhook()
{