mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-29 22:02:16 +02:00
Add UseDefinedRequestMatchers to ProxyAndRecordSettings (#821)
* . * UseDefinedRequestMatchers * ok * . * ClientIP * t * fix ut * . * cf * cf2
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
@@ -1,31 +1,39 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace WireMock.Admin.Mappings
|
namespace WireMock.Admin.Mappings;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cookie Model
|
||||||
|
/// </summary>
|
||||||
|
[FluentBuilder.AutoGenerateBuilder]
|
||||||
|
public class CookieModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cookie Model
|
/// Gets or sets the name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FluentBuilder.AutoGenerateBuilder]
|
public string Name { get; set; } = null!;
|
||||||
public class CookieModel
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; } = null!;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the matchers.
|
/// Gets or sets the matchers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<MatcherModel>? Matchers { get; set; }
|
public IList<MatcherModel>? Matchers { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the ignore case.
|
/// Gets or sets the ignore case.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool? IgnoreCase { get; set; }
|
public bool? IgnoreCase { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reject on match.
|
/// Reject on match.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool? RejectOnMatch { get; set; }
|
public bool? RejectOnMatch { get; set; }
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Operator to use when matchers are defined. [Optional]
|
||||||
|
/// - null = Same as "or".
|
||||||
|
/// - "or" = Only one pattern should match.
|
||||||
|
/// - "and" = All patterns should match.
|
||||||
|
/// - "average" = The average value from all patterns.
|
||||||
|
/// </summary>
|
||||||
|
public string? MatchOperator { get; set; }
|
||||||
}
|
}
|
||||||
@@ -54,5 +54,14 @@ namespace WireMock.Admin.Settings
|
|||||||
/// Prefer the Proxy Mapping over the saved Mapping (in case SaveMapping is set to <c>true</c>).
|
/// Prefer the Proxy Mapping over the saved Mapping (in case SaveMapping is set to <c>true</c>).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// public bool PreferProxyMapping { get; set; }
|
// public bool PreferProxyMapping { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When SaveMapping is set to <c>true</c>, this setting can be used to control the behavior of the generated request matchers for the new mapping.
|
||||||
|
/// - <c>false</c>, the default matchers will be used.
|
||||||
|
/// - <c>true</c>, the defined mappings in the request wil be used for the new mapping.
|
||||||
|
///
|
||||||
|
/// Default value is false.
|
||||||
|
/// </summary>
|
||||||
|
public bool UseDefinedRequestMatchers { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
|
using Stef.Validation;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Stef.Validation;
|
|
||||||
|
|
||||||
namespace WireMock.Matchers.Request;
|
namespace WireMock.Matchers.Request;
|
||||||
|
|
||||||
@@ -13,12 +12,13 @@ namespace WireMock.Matchers.Request;
|
|||||||
public class RequestMessageCookieMatcher : IRequestMatcher
|
public class RequestMessageCookieMatcher : IRequestMatcher
|
||||||
{
|
{
|
||||||
private readonly MatchBehaviour _matchBehaviour;
|
private readonly MatchBehaviour _matchBehaviour;
|
||||||
|
|
||||||
private readonly bool _ignoreCase;
|
private readonly bool _ignoreCase;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The functions
|
/// The functions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<IDictionary<string, string>, bool>[] Funcs { get; }
|
public Func<IDictionary<string, string>, bool>[]? Funcs { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name
|
/// The name
|
||||||
@@ -28,7 +28,7 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
|||||||
/// <value>
|
/// <value>
|
||||||
/// The matchers.
|
/// The matchers.
|
||||||
/// </value>
|
/// </value>
|
||||||
public IStringMatcher[] Matchers { get; }
|
public IStringMatcher[]? Matchers { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||||
@@ -37,15 +37,12 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
|||||||
/// <param name="pattern">The pattern.</param>
|
/// <param name="pattern">The pattern.</param>
|
||||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
|
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, string pattern, bool ignoreCase)
|
||||||
{
|
{
|
||||||
Guard.NotNull(name, nameof(name));
|
|
||||||
Guard.NotNull(pattern, nameof(pattern));
|
|
||||||
|
|
||||||
_matchBehaviour = matchBehaviour;
|
_matchBehaviour = matchBehaviour;
|
||||||
_ignoreCase = ignoreCase;
|
_ignoreCase = ignoreCase;
|
||||||
Name = name;
|
Name = Guard.NotNull(name);
|
||||||
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
|
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, Guard.NotNull(pattern), ignoreCase) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -55,10 +52,10 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
|||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="patterns">The patterns.</param>
|
/// <param name="patterns">The patterns.</param>
|
||||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params string[] patterns) :
|
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, bool ignoreCase, params string[] patterns) :
|
||||||
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
|
this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray())
|
||||||
{
|
{
|
||||||
Guard.NotNull(patterns, nameof(patterns));
|
Guard.NotNull(patterns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -68,14 +65,11 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
|||||||
/// <param name="name">The name.</param>
|
/// <param name="name">The name.</param>
|
||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
|
||||||
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, bool ignoreCase, [NotNull] params IStringMatcher[] matchers)
|
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, bool ignoreCase, params IStringMatcher[] matchers)
|
||||||
{
|
{
|
||||||
Guard.NotNull(name, nameof(name));
|
|
||||||
Guard.NotNull(matchers, nameof(matchers));
|
|
||||||
|
|
||||||
_matchBehaviour = matchBehaviour;
|
_matchBehaviour = matchBehaviour;
|
||||||
Name = name;
|
Name = Guard.NotNull(name);
|
||||||
Matchers = matchers;
|
Matchers = Guard.NotNull(matchers);
|
||||||
_ignoreCase = ignoreCase;
|
_ignoreCase = ignoreCase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,11 +77,12 @@ public class RequestMessageCookieMatcher : IRequestMatcher
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="funcs">The funcs.</param>
|
/// <param name="funcs">The funcs.</param>
|
||||||
public RequestMessageCookieMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)
|
public RequestMessageCookieMatcher(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||||
{
|
{
|
||||||
Guard.NotNull(funcs, nameof(funcs));
|
Guard.NotNull(funcs);
|
||||||
|
|
||||||
Funcs = funcs;
|
Funcs = funcs;
|
||||||
|
Name = string.Empty; // Not used when Func, but set to a non-null valid value.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ namespace WireMock.Matchers.Request;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RequestMessageParamMatcher : IRequestMatcher
|
public class RequestMessageParamMatcher : IRequestMatcher
|
||||||
{
|
{
|
||||||
private readonly MatchBehaviour _matchBehaviour;
|
/// <summary>
|
||||||
|
/// MatchBehaviour
|
||||||
|
/// </summary>
|
||||||
|
public MatchBehaviour MatchBehaviour { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The funcs
|
/// The funcs
|
||||||
@@ -63,7 +66,7 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
|||||||
/// <param name="matchers">The matchers.</param>
|
/// <param name="matchers">The matchers.</param>
|
||||||
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, IStringMatcher[]? matchers)
|
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, IStringMatcher[]? matchers)
|
||||||
{
|
{
|
||||||
_matchBehaviour = matchBehaviour;
|
MatchBehaviour = matchBehaviour;
|
||||||
Key = Guard.NotNull(key);
|
Key = Guard.NotNull(key);
|
||||||
IgnoreCase = ignoreCase;
|
IgnoreCase = ignoreCase;
|
||||||
Matchers = matchers;
|
Matchers = matchers;
|
||||||
@@ -81,7 +84,7 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||||
{
|
{
|
||||||
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
|
double score = MatchBehaviourHelper.Convert(MatchBehaviour, IsMatch(requestMessage));
|
||||||
return requestMatchResult.AddScore(GetType(), score);
|
return requestMatchResult.AddScore(GetType(), score);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ namespace WireMock.Owin
|
|||||||
_options.Logger.Error($"Providing a Response for Mapping '{result.Match?.Mapping?.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
|
_options.Logger.Error($"Providing a Response for Mapping '{result.Match?.Mapping?.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
|
||||||
response = ResponseMessageBuilder.Create(ex.Message, 500);
|
response = ResponseMessageBuilder.Create(ex.Message, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
var log = new LogEntry
|
var log = new LogEntry
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
|
using Stef.Validation;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Stef.Validation;
|
|
||||||
using WireMock.Constants;
|
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
using WireMock.Matchers;
|
using WireMock.Serialization;
|
||||||
using WireMock.RequestBuilders;
|
|
||||||
using WireMock.ResponseBuilders;
|
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
using WireMock.Types;
|
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Proxy;
|
namespace WireMock.Proxy;
|
||||||
@@ -18,13 +12,16 @@ namespace WireMock.Proxy;
|
|||||||
internal class ProxyHelper
|
internal class ProxyHelper
|
||||||
{
|
{
|
||||||
private readonly WireMockServerSettings _settings;
|
private readonly WireMockServerSettings _settings;
|
||||||
|
private readonly ProxyMappingConverter _proxyMappingConverter;
|
||||||
|
|
||||||
public ProxyHelper(WireMockServerSettings settings)
|
public ProxyHelper(WireMockServerSettings settings)
|
||||||
{
|
{
|
||||||
_settings = Guard.NotNull(settings);
|
_settings = Guard.NotNull(settings);
|
||||||
|
_proxyMappingConverter = new ProxyMappingConverter(settings, new GuidUtils());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(IResponseMessage Message, IMapping? Mapping)> SendAsync(
|
public async Task<(IResponseMessage Message, IMapping? Mapping)> SendAsync(
|
||||||
|
IMapping? mapping,
|
||||||
ProxyAndRecordSettings proxyAndRecordSettings,
|
ProxyAndRecordSettings proxyAndRecordSettings,
|
||||||
HttpClient client,
|
HttpClient client,
|
||||||
IRequestMessage requestMessage,
|
IRequestMessage requestMessage,
|
||||||
@@ -49,78 +46,13 @@ internal class ProxyHelper
|
|||||||
|
|
||||||
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
|
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate).ConfigureAwait(false);
|
||||||
|
|
||||||
IMapping? mapping = null;
|
IMapping? newMapping = null;
|
||||||
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||||
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
||||||
{
|
{
|
||||||
mapping = ToMapping(proxyAndRecordSettings, requestMessage, responseMessage);
|
newMapping = _proxyMappingConverter.ToMapping(mapping, proxyAndRecordSettings, requestMessage, responseMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (responseMessage, mapping);
|
return (responseMessage, newMapping);
|
||||||
}
|
|
||||||
|
|
||||||
private IMapping ToMapping(ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
|
||||||
{
|
|
||||||
var excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
|
|
||||||
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
|
||||||
|
|
||||||
var request = Request.Create();
|
|
||||||
request.WithPath(requestMessage.Path);
|
|
||||||
request.UsingMethod(requestMessage.Method);
|
|
||||||
|
|
||||||
requestMessage.Query?.Loop((key, value) => request.WithParam(key, false, value.ToArray()));
|
|
||||||
requestMessage.Cookies?.Loop((key, value) =>
|
|
||||||
{
|
|
||||||
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
request.WithCookie(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var allExcludedHeaders = new List<string>(excludedHeaders) { "Cookie" };
|
|
||||||
requestMessage.Headers?.Loop((key, value) =>
|
|
||||||
{
|
|
||||||
if (!allExcludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
request.WithHeader(key, value.ToArray());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
|
||||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
|
||||||
{
|
|
||||||
case BodyType.Json:
|
|
||||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson!, true, throwExceptionWhenMatcherFails));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BodyType.String:
|
|
||||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, MatchOperator.Or, requestMessage.BodyData.BodyAsString));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BodyType.Bytes:
|
|
||||||
request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var response = Response.Create(responseMessage);
|
|
||||||
|
|
||||||
return new Mapping
|
|
||||||
(
|
|
||||||
guid: Guid.NewGuid(),
|
|
||||||
title: $"Proxy Mapping for {requestMessage.Method} {requestMessage.Path}",
|
|
||||||
description: string.Empty,
|
|
||||||
path: null,
|
|
||||||
settings: _settings,
|
|
||||||
request,
|
|
||||||
response,
|
|
||||||
priority: WireMockConstants.ProxyPriority, // This was 0
|
|
||||||
scenario: null,
|
|
||||||
executionConditionState: null,
|
|
||||||
nextState: null,
|
|
||||||
stateTimes: null,
|
|
||||||
webhooks: null,
|
|
||||||
useWebhooksFireAndForget: null,
|
|
||||||
timeSettings: null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, bool, MatchBehaviour)"/>
|
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, bool, MatchBehaviour)"/>
|
||||||
public IRequestBuilder WithParam(string key, bool ignoreCase, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
public IRequestBuilder WithParam(string key, bool ignoreCase, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||||
{
|
{
|
||||||
Guard.NotNull(key, nameof(key));
|
Guard.NotNull(key);
|
||||||
|
|
||||||
_requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, ignoreCase));
|
_requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, ignoreCase));
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -271,6 +271,7 @@ public partial class Response : IResponseBuilder
|
|||||||
var proxyHelper = new ProxyHelper(settings);
|
var proxyHelper = new ProxyHelper(settings);
|
||||||
|
|
||||||
return await proxyHelper.SendAsync(
|
return await proxyHelper.SendAsync(
|
||||||
|
mapping,
|
||||||
ProxyAndRecordSettings,
|
ProxyAndRecordSettings,
|
||||||
_httpClientForProxy,
|
_httpClientForProxy,
|
||||||
requestMessage,
|
requestMessage,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ internal class MappingConverter
|
|||||||
|
|
||||||
public MappingConverter(MatcherMapper mapper)
|
public MappingConverter(MatcherMapper mapper)
|
||||||
{
|
{
|
||||||
_mapper = Guard.NotNull(mapper, nameof(mapper));
|
_mapper = Guard.NotNull(mapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MappingModel ToMappingModel(IMapping mapping)
|
public MappingModel ToMappingModel(IMapping mapping)
|
||||||
|
|||||||
181
src/WireMock.Net/Serialization/ProxyMappingConverter.cs
Normal file
181
src/WireMock.Net/Serialization/ProxyMappingConverter.cs
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
using Stef.Validation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using WireMock.Constants;
|
||||||
|
using WireMock.Matchers;
|
||||||
|
using WireMock.Matchers.Request;
|
||||||
|
using WireMock.RequestBuilders;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
|
using WireMock.Settings;
|
||||||
|
using WireMock.Types;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
|
namespace WireMock.Serialization;
|
||||||
|
|
||||||
|
internal class ProxyMappingConverter
|
||||||
|
{
|
||||||
|
private readonly WireMockServerSettings _settings;
|
||||||
|
private readonly IGuidUtils _guidUtils;
|
||||||
|
|
||||||
|
public ProxyMappingConverter(WireMockServerSettings settings, IGuidUtils guidUtils)
|
||||||
|
{
|
||||||
|
_settings = Guard.NotNull(settings);
|
||||||
|
_guidUtils = Guard.NotNull(guidUtils);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMapping ToMapping(IMapping? mapping, ProxyAndRecordSettings proxyAndRecordSettings, IRequestMessage requestMessage, ResponseMessage responseMessage)
|
||||||
|
{
|
||||||
|
var request = (Request?)mapping?.RequestMatcher;
|
||||||
|
var clientIPMatcher = request?.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
|
||||||
|
var pathMatcher = request?.GetRequestMessageMatcher<RequestMessagePathMatcher>();
|
||||||
|
var headerMatchers = request?.GetRequestMessageMatchers<RequestMessageHeaderMatcher>();
|
||||||
|
var cookieMatchers = request?.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
|
||||||
|
var paramMatchers = request?.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
||||||
|
var methodMatcher = request?.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
||||||
|
var bodyMatcher = request?.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||||
|
|
||||||
|
var useDefinedRequestMatchers = proxyAndRecordSettings.UseDefinedRequestMatchers;
|
||||||
|
|
||||||
|
var excludedHeaders = new List<string>(proxyAndRecordSettings.ExcludedHeaders ?? new string[] { }) { "Cookie" };
|
||||||
|
var excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
||||||
|
|
||||||
|
var newRequest = Request.Create();
|
||||||
|
|
||||||
|
// ClientIP
|
||||||
|
if (useDefinedRequestMatchers && clientIPMatcher?.Matchers is not null)
|
||||||
|
{
|
||||||
|
newRequest.WithClientIP(clientIPMatcher.MatchOperator, clientIPMatcher.Matchers.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path
|
||||||
|
if (useDefinedRequestMatchers && pathMatcher?.Matchers is not null)
|
||||||
|
{
|
||||||
|
newRequest.WithPath(pathMatcher.MatchOperator, pathMatcher.Matchers.ToArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newRequest.WithPath(requestMessage.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method
|
||||||
|
if (useDefinedRequestMatchers && methodMatcher is not null)
|
||||||
|
{
|
||||||
|
newRequest.UsingMethod(methodMatcher.Methods);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newRequest.UsingMethod(requestMessage.Method);
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryParams
|
||||||
|
if (useDefinedRequestMatchers && paramMatchers is not null)
|
||||||
|
{
|
||||||
|
foreach (var paramMatcher in paramMatchers)
|
||||||
|
{
|
||||||
|
newRequest.WithParam(paramMatcher.Key, paramMatcher.MatchBehaviour, paramMatcher.Matchers!.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestMessage.Query?.Loop((key, value) => newRequest.WithParam(key, false, value.ToArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cookies
|
||||||
|
if (useDefinedRequestMatchers && cookieMatchers is not null)
|
||||||
|
{
|
||||||
|
foreach (var cookieMatcher in cookieMatchers.Where(hm => hm.Matchers is not null))
|
||||||
|
{
|
||||||
|
if (!excludedCookies.Contains(cookieMatcher.Name, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
newRequest.WithCookie(cookieMatcher.Name, cookieMatcher.Matchers!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestMessage.Cookies?.Loop((key, value) =>
|
||||||
|
{
|
||||||
|
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
newRequest.WithCookie(key, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headers
|
||||||
|
if (useDefinedRequestMatchers && headerMatchers is not null)
|
||||||
|
{
|
||||||
|
foreach (var headerMatcher in headerMatchers.Where(hm => hm.Matchers is not null))
|
||||||
|
{
|
||||||
|
if (!excludedHeaders.Contains(headerMatcher.Name, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
newRequest.WithHeader(headerMatcher.Name, headerMatcher.Matchers!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
requestMessage.Headers?.Loop((key, value) =>
|
||||||
|
{
|
||||||
|
if (!excludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
newRequest.WithHeader(key, value.ToArray());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body
|
||||||
|
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||||
|
if (useDefinedRequestMatchers && bodyMatcher?.Matchers is not null)
|
||||||
|
{
|
||||||
|
newRequest.WithBody(bodyMatcher.Matchers);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||||
|
{
|
||||||
|
case BodyType.Json:
|
||||||
|
newRequest.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson!, true, throwExceptionWhenMatcherFails));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BodyType.String:
|
||||||
|
newRequest.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, MatchOperator.Or, requestMessage.BodyData.BodyAsString));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BodyType.Bytes:
|
||||||
|
newRequest.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Title
|
||||||
|
var title = useDefinedRequestMatchers && !string.IsNullOrEmpty(mapping?.Title) ?
|
||||||
|
mapping!.Title :
|
||||||
|
$"Proxy Mapping for {requestMessage.Method} {requestMessage.Path}";
|
||||||
|
|
||||||
|
// Description
|
||||||
|
var description = useDefinedRequestMatchers && !string.IsNullOrEmpty(mapping?.Description) ?
|
||||||
|
mapping!.Description :
|
||||||
|
$"Proxy Mapping for {requestMessage.Method} {requestMessage.Path}";
|
||||||
|
|
||||||
|
return new Mapping
|
||||||
|
(
|
||||||
|
guid: _guidUtils.NewGuid(),
|
||||||
|
title: title,
|
||||||
|
description: description,
|
||||||
|
path: null,
|
||||||
|
settings: _settings,
|
||||||
|
requestMatcher: newRequest,
|
||||||
|
provider: Response.Create(responseMessage),
|
||||||
|
priority: WireMockConstants.ProxyPriority, // This was 0
|
||||||
|
scenario: null,
|
||||||
|
executionConditionState: null,
|
||||||
|
nextState: null,
|
||||||
|
stateTimes: null,
|
||||||
|
webhooks: null,
|
||||||
|
useWebhooksFireAndForget: null,
|
||||||
|
timeSettings: null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -236,6 +236,7 @@ public partial class WireMockServer
|
|||||||
var proxyHelper = new ProxyHelper(settings);
|
var proxyHelper = new ProxyHelper(settings);
|
||||||
|
|
||||||
var (responseMessage, mapping) = await proxyHelper.SendAsync(
|
var (responseMessage, mapping) = await proxyHelper.SendAsync(
|
||||||
|
null,
|
||||||
_settings.ProxyAndRecordSettings!,
|
_settings.ProxyAndRecordSettings!,
|
||||||
_httpClientForProxy!,
|
_httpClientForProxy!,
|
||||||
requestMessage,
|
requestMessage,
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public partial class WireMockServer
|
|||||||
{
|
{
|
||||||
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
|
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithCookie(
|
requestBuilder = requestBuilder.WithCookie(
|
||||||
cookieModel.Name,
|
cookieModel.Name,
|
||||||
cookieModel.IgnoreCase == true,
|
cookieModel.IgnoreCase == true,
|
||||||
cookieModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
cookieModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||||
|
|||||||
@@ -49,4 +49,13 @@ public class ProxyAndRecordSettings : HttpClientSettings
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
//[PublicAPI]
|
//[PublicAPI]
|
||||||
//public bool PreferProxyMapping { get; set; }
|
//public bool PreferProxyMapping { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When SaveMapping is set to <c>true</c>, this setting can be used to control the behavior of the generated request matchers for the new mapping.
|
||||||
|
/// - <c>false</c>, the default matchers will be used.
|
||||||
|
/// - <c>true</c>, the defined mappings in the request wil be used for the new mapping.
|
||||||
|
///
|
||||||
|
/// Default value is false.
|
||||||
|
/// </summary>
|
||||||
|
public bool UseDefinedRequestMatchers { get; set; }
|
||||||
}
|
}
|
||||||
@@ -92,6 +92,7 @@ public static class WireMockServerSettingsParser
|
|||||||
SaveMapping = parser.GetBoolValue("SaveMapping"),
|
SaveMapping = parser.GetBoolValue("SaveMapping"),
|
||||||
SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern", "*"),
|
SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern", "*"),
|
||||||
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
|
||||||
|
UseDefinedRequestMatchers = parser.GetBoolValue(nameof(ProxyAndRecordSettings.UseDefinedRequestMatchers)),
|
||||||
Url = proxyUrl!
|
Url = proxyUrl!
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
16
src/WireMock.Net/Util/GuidUtils.cs
Normal file
16
src/WireMock.Net/Util/GuidUtils.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace WireMock.Util;
|
||||||
|
|
||||||
|
internal interface IGuidUtils
|
||||||
|
{
|
||||||
|
Guid NewGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class GuidUtils : IGuidUtils
|
||||||
|
{
|
||||||
|
public Guid NewGuid()
|
||||||
|
{
|
||||||
|
return Guid.NewGuid();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
using System;
|
||||||
|
using Moq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.IO;
|
||||||
|
using FluentAssertions;
|
||||||
|
using WireMock.Matchers;
|
||||||
|
using WireMock.RequestBuilders;
|
||||||
|
using WireMock.Serialization;
|
||||||
|
using WireMock.Settings;
|
||||||
|
using WireMock.Util;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.Serialization;
|
||||||
|
|
||||||
|
public class ProxyMappingConverterTests
|
||||||
|
{
|
||||||
|
private readonly WireMockServerSettings _settings = new();
|
||||||
|
|
||||||
|
private readonly MappingConverter _mappingConverter;
|
||||||
|
|
||||||
|
private readonly ProxyMappingConverter _sut;
|
||||||
|
|
||||||
|
public ProxyMappingConverterTests()
|
||||||
|
{
|
||||||
|
var guidUtilsMock = new Mock<IGuidUtils>();
|
||||||
|
guidUtilsMock.Setup(g => g.NewGuid()).Returns(Guid.Parse("ff55ac0a-fea9-4d7b-be74-5e483a2c1305"));
|
||||||
|
|
||||||
|
_mappingConverter = new MappingConverter(new MatcherMapper(_settings));
|
||||||
|
|
||||||
|
_sut = new ProxyMappingConverter(_settings, guidUtilsMock.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ToMapping_UseDefinedRequestMatchers_True()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var proxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
UseDefinedRequestMatchers = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var request = Request.Create()
|
||||||
|
.UsingPost()
|
||||||
|
.WithPath("x")
|
||||||
|
.WithParam("p1", "p1-v")
|
||||||
|
.WithParam("p2", "p2-v")
|
||||||
|
.WithHeader("Content-Type", new ContentTypeMatcher("text/plain"))
|
||||||
|
.WithCookie("c", "x")
|
||||||
|
.WithBody(new RegexMatcher("<RequestType>Auth</RequestType"));
|
||||||
|
|
||||||
|
var mappingMock = new Mock<IMapping>();
|
||||||
|
mappingMock.SetupGet(m => m.RequestMatcher).Returns(request);
|
||||||
|
mappingMock.SetupGet(m => m.Title).Returns("my title");
|
||||||
|
mappingMock.SetupGet(m => m.Description).Returns("my description");
|
||||||
|
|
||||||
|
var requestMessageMock = new Mock<IRequestMessage>();
|
||||||
|
|
||||||
|
var responseMessage = new ResponseMessage();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var proxyMapping = _sut.ToMapping(mappingMock.Object, proxyAndRecordSettings, requestMessageMock.Object, responseMessage);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var model = _mappingConverter.ToMappingModel(proxyMapping);
|
||||||
|
var json = JsonConvert.SerializeObject(model, JsonSerializationConstants.JsonSerializerSettingsDefault);
|
||||||
|
var expected = File.ReadAllText(Path.Combine("../../../", "Serialization", "files", "proxy.json"));
|
||||||
|
|
||||||
|
json.Should().Be(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
72
test/WireMock.Net.Tests/Serialization/files/proxy.json
Normal file
72
test/WireMock.Net.Tests/Serialization/files/proxy.json
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"Guid": "ff55ac0a-fea9-4d7b-be74-5e483a2c1305",
|
||||||
|
"Title": "my title",
|
||||||
|
"Description": "my description",
|
||||||
|
"Priority": -2000000,
|
||||||
|
"Request": {
|
||||||
|
"Path": {
|
||||||
|
"Matchers": [
|
||||||
|
{
|
||||||
|
"Name": "WildcardMatcher",
|
||||||
|
"Pattern": "x",
|
||||||
|
"IgnoreCase": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Methods": [
|
||||||
|
"POST"
|
||||||
|
],
|
||||||
|
"Headers": [
|
||||||
|
{
|
||||||
|
"Name": "Content-Type",
|
||||||
|
"Matchers": [
|
||||||
|
{
|
||||||
|
"Name": "ContentTypeMatcher",
|
||||||
|
"Pattern": "text/plain",
|
||||||
|
"IgnoreCase": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Cookies": [
|
||||||
|
{
|
||||||
|
"Name": "c",
|
||||||
|
"Matchers": [
|
||||||
|
{
|
||||||
|
"Name": "WildcardMatcher",
|
||||||
|
"Pattern": "x",
|
||||||
|
"IgnoreCase": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Params": [
|
||||||
|
{
|
||||||
|
"Name": "p1",
|
||||||
|
"Matchers": [
|
||||||
|
{
|
||||||
|
"Name": "ExactMatcher",
|
||||||
|
"Pattern": "p1-v"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "p2",
|
||||||
|
"Matchers": [
|
||||||
|
{
|
||||||
|
"Name": "ExactMatcher",
|
||||||
|
"Pattern": "p2-v"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Body": {
|
||||||
|
"Matcher": {
|
||||||
|
"Name": "RegexMatcher",
|
||||||
|
"Pattern": "<RequestType>Auth</RequestType",
|
||||||
|
"IgnoreCase": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Response": {}
|
||||||
|
}
|
||||||
@@ -85,6 +85,9 @@
|
|||||||
<None Update="responsebody.json">
|
<None Update="responsebody.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Serialization\files\proxy.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="__admin\mappings.org\*.json">
|
<None Update="__admin\mappings.org\*.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
@@ -105,6 +108,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Pact\files\" />
|
<Folder Include="Pact\files\" />
|
||||||
|
<Folder Include="Serialization\files\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NFluent;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@@ -5,11 +8,9 @@ using System.Net.Http;
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
using WireMock.Constants;
|
||||||
using Moq;
|
|
||||||
using NFluent;
|
|
||||||
using WireMock.Admin.Mappings;
|
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
|
using WireMock.Matchers;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
@@ -119,6 +120,61 @@ public class WireMockServerProxyTests
|
|||||||
server.Mappings.Should().HaveCount(28);
|
server.Mappings.Should().HaveCount(28);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WireMockServer_Proxy_With_SaveMappingToFile_Is_True_ShouldSaveMappingToFile()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
string path = $"/prx_{Guid.NewGuid()}";
|
||||||
|
var title = "IndexFile";
|
||||||
|
var description = "IndexFile_Test";
|
||||||
|
var stringBody = "<pretendXml>value</pretendXml>";
|
||||||
|
var serverForProxyForwarding = WireMockServer.Start();
|
||||||
|
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
||||||
|
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
||||||
|
|
||||||
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
Url = serverForProxyForwarding.Urls[0],
|
||||||
|
SaveMapping = false,
|
||||||
|
SaveMappingToFile = true
|
||||||
|
},
|
||||||
|
FileSystemHandler = fileSystemHandlerMock.Object
|
||||||
|
};
|
||||||
|
|
||||||
|
var server = WireMockServer.Start(settings);
|
||||||
|
server.Given(Request.Create()
|
||||||
|
.WithPath("/*")
|
||||||
|
.WithBody(new RegexMatcher(stringBody)))
|
||||||
|
.WithTitle(title)
|
||||||
|
.WithDescription(description)
|
||||||
|
.AtPriority(WireMockConstants.ProxyPriority)
|
||||||
|
.RespondWith(Response.Create().WithProxy(new ProxyAndRecordSettings
|
||||||
|
{
|
||||||
|
Url = serverForProxyForwarding.Urls[0],
|
||||||
|
SaveMapping = false,
|
||||||
|
SaveMappingToFile = true,
|
||||||
|
UseDefinedRequestMatchers = true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var requestMessage = new HttpRequestMessage
|
||||||
|
{
|
||||||
|
Method = HttpMethod.Post,
|
||||||
|
RequestUri = new Uri($"{server.Urls[0]}{path}"),
|
||||||
|
Content = new StringContent(stringBody)
|
||||||
|
};
|
||||||
|
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
|
||||||
|
await new HttpClient(httpClientHandler).SendAsync(requestMessage).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
server.Mappings.Should().HaveCount(2);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
fileSystemHandlerMock.Verify(f => f.WriteMappingFile($"m{System.IO.Path.DirectorySeparatorChar}{title}.json", It.IsRegex(stringBody)), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockServer_Proxy_With_SaveMapping_Is_False_And_SaveMappingToFile_Is_True_ShouldSaveMappingToFile()
|
public async Task WireMockServer_Proxy_With_SaveMapping_Is_False_And_SaveMappingToFile_Is_True_ShouldSaveMappingToFile()
|
||||||
{
|
{
|
||||||
@@ -735,8 +791,6 @@ public class WireMockServerProxyTests
|
|||||||
content.Should().NotBeEmpty();
|
content.Should().NotBeEmpty();
|
||||||
|
|
||||||
server.LogEntries.Should().HaveCount(1);
|
server.LogEntries.Should().HaveCount(1);
|
||||||
var status = ((StatusModel)server.LogEntries.First().ResponseMessage.BodyData.BodyAsJson).Status;
|
|
||||||
|
|
||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user