Initial support for converting the mappings to a Pact(flow) json file (#748)

* WithDescription

* WithConsumer / WithProvider

* x

* .

* .

* .

* .

* fix

* pact

* nullable

* ficx

* .

* fix
This commit is contained in:
Stef Heyenrath
2022-04-22 16:17:50 +02:00
committed by GitHub
parent b06b3c8e8b
commit a6ee2dacc7
93 changed files with 1876 additions and 1065 deletions

View File

@@ -38,6 +38,13 @@ namespace WireMock.Server
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
IRespondWithAProvider WithTitle(string title);
/// <summary>
/// Define a description for this mapping.
/// </summary>
/// <param name="description">The description.</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
IRespondWithAProvider WithDescription(string description);
/// <summary>
/// Define the full filepath for this mapping.
/// </summary>

View File

@@ -21,6 +21,7 @@ namespace WireMock.Server
{
private int _priority;
private string _title;
private string _description;
private string _path;
private string _executionConditionState;
private string _nextState;
@@ -58,16 +59,16 @@ namespace WireMock.Server
/// <param name="provider">The provider.</param>
public void RespondWith(IResponseProvider provider)
{
_registrationCallback(new Mapping(Guid, _title, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhooks, TimeSettings), _saveToFile);
_registrationCallback(new Mapping(Guid, _title, _description, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhooks, TimeSettings), _saveToFile);
}
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>
/// <inheritdoc />
public IRespondWithAProvider WithGuid(string guid)
{
return WithGuid(Guid.Parse(guid));
}
/// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>
/// <inheritdoc />
public IRespondWithAProvider WithGuid(Guid guid)
{
Guid = guid;
@@ -75,7 +76,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.WithTitle"/>
/// <inheritdoc />
public IRespondWithAProvider WithTitle(string title)
{
_title = title;
@@ -83,6 +84,14 @@ namespace WireMock.Server
return this;
}
/// <inheritdoc />
public IRespondWithAProvider WithDescription(string description)
{
_description = description;
return this;
}
/// <see cref="IRespondWithAProvider.WithPath"/>
public IRespondWithAProvider WithPath(string path)
{
@@ -91,7 +100,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.AtPriority"/>
/// <inheritdoc />
public IRespondWithAProvider AtPriority(int priority)
{
_priority = priority;
@@ -99,7 +108,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.InScenario(string)"/>
/// <inheritdoc />
public IRespondWithAProvider InScenario(string scenario)
{
_scenario = scenario;
@@ -107,13 +116,13 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.InScenario(int)"/>
/// <inheritdoc />
public IRespondWithAProvider InScenario(int scenario)
{
return InScenario(scenario.ToString());
}
/// <see cref="IRespondWithAProvider.WhenStateIs(string)"/>
/// <inheritdoc />
public IRespondWithAProvider WhenStateIs(string state)
{
if (string.IsNullOrEmpty(_scenario))
@@ -126,13 +135,13 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.WhenStateIs(int)"/>
/// <inheritdoc />
public IRespondWithAProvider WhenStateIs(int state)
{
return WhenStateIs(state.ToString());
}
/// <see cref="IRespondWithAProvider.WillSetStateTo(string, int?)"/>
/// <inheritdoc />
public IRespondWithAProvider WillSetStateTo(string state, int? times = 1)
{
if (string.IsNullOrEmpty(_scenario))
@@ -146,7 +155,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.WillSetStateTo(int, int?)"/>
/// <inheritdoc />
public IRespondWithAProvider WillSetStateTo(int state, int? times = 1)
{
return WillSetStateTo(state.ToString(), times);
@@ -162,7 +171,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.WithWebhook(IWebhook[])"/>
/// <inheritdoc />
public IRespondWithAProvider WithWebhook(params IWebhook[] webhooks)
{
Guard.HasNoNulls(webhooks, nameof(webhooks));
@@ -172,7 +181,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.WithWebhook(string, string, IDictionary{string, WireMockList{string}}, string, bool, TransformerType)"/>
/// <inheritdoc />
public IRespondWithAProvider WithWebhook(
[NotNull] string url,
[CanBeNull] string method = "post",
@@ -196,7 +205,7 @@ namespace WireMock.Server
return this;
}
/// <see cref="IRespondWithAProvider.WithWebhook(string, string, IDictionary{string, WireMockList{string}}, object, bool, TransformerType)"/>
/// <inheritdoc />
public IRespondWithAProvider WithWebhook(
[NotNull] string url,
[CanBeNull] string method = "post",

View File

@@ -44,12 +44,12 @@ public partial class WireMockServer
private const string AdminScenarios = "/__admin/scenarios";
private const string QueryParamReloadStaticMappings = "reloadStaticMappings";
private readonly Guid _proxyMappingGuid = new Guid("e59914fd-782e-428e-91c1-4810ffb86567");
private readonly Guid _proxyMappingGuid = new("e59914fd-782e-428e-91c1-4810ffb86567");
private readonly RegexMatcher _adminRequestContentTypeJson = new ContentTypeMatcher(ContentTypeJson, true);
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private EnhancedFileSystemWatcher _enhancedFileSystemWatcher;
private EnhancedFileSystemWatcher? _enhancedFileSystemWatcher;
#region InitAdmin
private void InitAdmin()
@@ -108,7 +108,7 @@ public partial class WireMockServer
#region StaticMappings
/// <inheritdoc cref="IWireMockServer.SaveStaticMappings" />
[PublicAPI]
public void SaveStaticMappings([CanBeNull] string folder = null)
public void SaveStaticMappings(string? folder = null)
{
foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
{
@@ -118,7 +118,7 @@ public partial class WireMockServer
/// <inheritdoc cref="IWireMockServer.ReadStaticMappings" />
[PublicAPI]
public void ReadStaticMappings([CanBeNull] string folder = null)
public void ReadStaticMappings(string? folder = null)
{
if (folder == null)
{
@@ -207,8 +207,7 @@ public partial class WireMockServer
#endregion
#region Proxy and Record
[CanBeNull]
private HttpClient _httpClientForProxy;
private HttpClient? _httpClientForProxy;
private void InitProxyAndRecord(WireMockServerSettings settings)
{
@@ -230,7 +229,7 @@ public partial class WireMockServer
proxyRespondProvider.RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
}
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, WireMockServerSettings settings)
private async Task<IResponseMessage> ProxyAndRecordAsync(IRequestMessage requestMessage, WireMockServerSettings settings)
{
var requestUri = new Uri(requestMessage.Url);
var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url);
@@ -263,7 +262,7 @@ public partial class WireMockServer
#endregion
#region Settings
private ResponseMessage SettingsGet(RequestMessage requestMessage)
private IResponseMessage SettingsGet(IRequestMessage requestMessage)
{
var model = new SettingsModel
{
@@ -290,7 +289,7 @@ public partial class WireMockServer
return ToJson(model);
}
private ResponseMessage SettingsUpdate(RequestMessage requestMessage)
private IResponseMessage SettingsUpdate(IRequestMessage requestMessage)
{
var settings = DeserializeObject<SettingsModel>(requestMessage);
@@ -335,7 +334,7 @@ public partial class WireMockServer
#endregion Settings
#region Mapping/{guid}
private ResponseMessage MappingGet(RequestMessage requestMessage)
private IResponseMessage MappingGet(IRequestMessage requestMessage)
{
Guid guid = ParseGuidFromRequestMessage(requestMessage);
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
@@ -351,7 +350,7 @@ public partial class WireMockServer
return ToJson(model);
}
private ResponseMessage MappingPut(RequestMessage requestMessage)
private IResponseMessage MappingPut(IRequestMessage requestMessage)
{
Guid guid = ParseGuidFromRequestMessage(requestMessage);
@@ -361,7 +360,7 @@ public partial class WireMockServer
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);
}
private ResponseMessage MappingDelete(RequestMessage requestMessage)
private IResponseMessage MappingDelete(IRequestMessage requestMessage)
{
Guid guid = ParseGuidFromRequestMessage(requestMessage);
@@ -373,14 +372,14 @@ public partial class WireMockServer
return ResponseMessageBuilder.Create("Mapping not found", 404);
}
private Guid ParseGuidFromRequestMessage(RequestMessage requestMessage)
private Guid ParseGuidFromRequestMessage(IRequestMessage requestMessage)
{
return Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
}
#endregion Mapping/{guid}
#region Mappings
private ResponseMessage MappingsSave(RequestMessage requestMessage)
private IResponseMessage MappingsSave(IRequestMessage requestMessage)
{
SaveStaticMappings();
@@ -392,12 +391,12 @@ public partial class WireMockServer
return Mappings.Where(m => !m.IsAdminInterface).Select(_mappingConverter.ToMappingModel);
}
private ResponseMessage MappingsGet(RequestMessage requestMessage)
private IResponseMessage MappingsGet(IRequestMessage requestMessage)
{
return ToJson(ToMappingModels());
}
private ResponseMessage MappingsPost(RequestMessage requestMessage)
private IResponseMessage MappingsPost(IRequestMessage requestMessage)
{
try
{
@@ -427,7 +426,7 @@ public partial class WireMockServer
}
}
private Guid? ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string path = null)
private Guid? ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string? path = null)
{
Guard.NotNull(mappingModel, nameof(mappingModel));
Guard.NotNull(mappingModel.Request, nameof(mappingModel.Request));
@@ -494,7 +493,7 @@ public partial class WireMockServer
return respondProvider.Guid;
}
private ResponseMessage MappingsDelete(RequestMessage requestMessage)
private IResponseMessage MappingsDelete(IRequestMessage requestMessage)
{
if (!string.IsNullOrEmpty(requestMessage.Body))
{
@@ -519,7 +518,7 @@ public partial class WireMockServer
}
}
private IEnumerable<Guid> MappingsDeleteMappingFromBody(RequestMessage requestMessage)
private IEnumerable<Guid> MappingsDeleteMappingFromBody(IRequestMessage requestMessage)
{
var deletedGuids = new List<Guid>();
@@ -555,7 +554,7 @@ public partial class WireMockServer
return deletedGuids;
}
private ResponseMessage MappingsReset(RequestMessage requestMessage)
private IResponseMessage MappingsReset(IRequestMessage requestMessage)
{
ResetMappings();
@@ -575,7 +574,7 @@ public partial class WireMockServer
#endregion Mappings
#region Request/{guid}
private ResponseMessage RequestGet(RequestMessage requestMessage)
private IResponseMessage RequestGet(IRequestMessage requestMessage)
{
Guid guid = ParseGuidFromRequestMessage(requestMessage);
var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
@@ -591,7 +590,7 @@ public partial class WireMockServer
return ToJson(model);
}
private ResponseMessage RequestDelete(RequestMessage requestMessage)
private IResponseMessage RequestDelete(IRequestMessage requestMessage)
{
Guid guid = ParseGuidFromRequestMessage(requestMessage);
@@ -605,7 +604,7 @@ public partial class WireMockServer
#endregion Request/{guid}
#region Requests
private ResponseMessage RequestsGet(RequestMessage requestMessage)
private IResponseMessage RequestsGet(IRequestMessage requestMessage)
{
var result = LogEntries
.Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
@@ -614,7 +613,7 @@ public partial class WireMockServer
return ToJson(result);
}
private ResponseMessage RequestsDelete(RequestMessage requestMessage)
private IResponseMessage RequestsDelete(IRequestMessage requestMessage)
{
ResetLogEntries();
@@ -623,7 +622,7 @@ public partial class WireMockServer
#endregion Requests
#region Requests/find
private ResponseMessage RequestsFind(RequestMessage requestMessage)
private IResponseMessage RequestsFind(IRequestMessage requestMessage)
{
var requestModel = DeserializeObject<RequestModel>(requestMessage);
@@ -646,7 +645,7 @@ public partial class WireMockServer
#endregion Requests/find
#region Scenarios
private ResponseMessage ScenariosGet(RequestMessage requestMessage)
private IResponseMessage ScenariosGet(IRequestMessage requestMessage)
{
var scenariosStates = Scenarios.Values.Select(s => new ScenarioStateModel
{
@@ -660,7 +659,7 @@ public partial class WireMockServer
return ToJson(scenariosStates, true);
}
private ResponseMessage ScenariosReset(RequestMessage requestMessage)
private IResponseMessage ScenariosReset(IRequestMessage requestMessage)
{
ResetScenarios();
@@ -668,7 +667,29 @@ public partial class WireMockServer
}
#endregion
private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
/// <summary>
/// This stores details about the consumer of the interaction.
/// </summary>
/// <param name="consumer">the consumer</param>
[PublicAPI]
public WireMockServer WithConsumer(string consumer)
{
Consumer = consumer;
return this;
}
/// <summary>
/// This stores details about the provider of the interaction.
/// </summary>
/// <param name="provider">the provider</param>
[PublicAPI]
public WireMockServer WithProvider(string provider)
{
Provider = provider;
return this;
}
private IRequestBuilder? InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
{
IRequestBuilder requestBuilder = Request.Create();
@@ -743,7 +764,7 @@ public partial class WireMockServer
headerModel.Name,
headerModel.IgnoreCase == true,
headerModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
headerModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray()
headerModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray()
);
}
}
@@ -756,16 +777,16 @@ public partial class WireMockServer
cookieModel.Name,
cookieModel.IgnoreCase == true,
cookieModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
cookieModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
cookieModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
}
}
if (requestModel.Params != null)
{
foreach (var paramModel in requestModel.Params.Where(p => p != null && p.Matchers != null))
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: { } }))
{
bool ignoreCase = paramModel.IgnoreCase == true;
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
}
}
@@ -897,12 +918,12 @@ public partial class WireMockServer
};
}
private Encoding ToEncoding(EncodingModel encodingModel)
private Encoding? ToEncoding(EncodingModel? encodingModel)
{
return encodingModel != null ? Encoding.GetEncoding(encodingModel.CodePage) : null;
}
private T DeserializeObject<T>(RequestMessage requestMessage)
private T? DeserializeObject<T>(IRequestMessage requestMessage)
{
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
{
@@ -917,9 +938,9 @@ public partial class WireMockServer
return default(T);
}
private T[] DeserializeRequestMessageToArray<T>(RequestMessage requestMessage)
private T[] DeserializeRequestMessageToArray<T>(IRequestMessage requestMessage)
{
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
if (requestMessage.BodyData?.DetectedBodyType == BodyType.Json)
{
var bodyAsJson = requestMessage.BodyData.BodyAsJson;

View File

@@ -13,7 +13,7 @@ namespace WireMock.Server
private static readonly Encoding[] FileBodyIsString = { Encoding.UTF8, Encoding.ASCII };
#region Files/{filename}
private ResponseMessage FilePost(RequestMessage requestMessage)
private IResponseMessage FilePost(IRequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
@@ -28,7 +28,7 @@ namespace WireMock.Server
return ResponseMessageBuilder.Create("File created");
}
private ResponseMessage FilePut(RequestMessage requestMessage)
private IResponseMessage FilePut(IRequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
@@ -43,7 +43,7 @@ namespace WireMock.Server
return ResponseMessageBuilder.Create("File updated");
}
private ResponseMessage FileGet(RequestMessage requestMessage)
private IResponseMessage FileGet(IRequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
@@ -79,7 +79,7 @@ namespace WireMock.Server
/// Note: Response is returned with no body as a head request doesn't accept a body, only the status code.
/// </summary>
/// <param name="requestMessage">The request message.</param>
private ResponseMessage FileHead(RequestMessage requestMessage)
private IResponseMessage FileHead(IRequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
@@ -92,7 +92,7 @@ namespace WireMock.Server
return ResponseMessageBuilder.Create(204);
}
private ResponseMessage FileDelete(RequestMessage requestMessage)
private IResponseMessage FileDelete(IRequestMessage requestMessage)
{
string filename = GetFileNameFromRequestMessage(requestMessage);
@@ -106,7 +106,7 @@ namespace WireMock.Server
return ResponseMessageBuilder.Create("File deleted.");
}
private string GetFileNameFromRequestMessage(RequestMessage requestMessage)
private string GetFileNameFromRequestMessage(IRequestMessage requestMessage)
{
return Path.GetFileName(requestMessage.Path.Substring(AdminFiles.Length + 1));
}

View File

@@ -21,7 +21,7 @@ namespace WireMock.Server
/// </summary>
/// <param name="path">The path to the WireMock.org mapping json file.</param>
[PublicAPI]
public void ReadStaticWireMockOrgMappingAndAddOrUpdate([NotNull] string path)
public void ReadStaticWireMockOrgMappingAndAddOrUpdate(string path)
{
Guard.NotNull(path, nameof(path));
@@ -44,7 +44,7 @@ namespace WireMock.Server
}
}
private ResponseMessage MappingsPostWireMockOrg(RequestMessage requestMessage)
private IResponseMessage MappingsPostWireMockOrg(IRequestMessage requestMessage)
{
try
{

View File

@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.Linq;
using WireMock.Admin.Mappings;
using WireMock.Pact.Models.V2;
using WireMock.Util;
namespace WireMock.Server;
public partial class WireMockServer
{
private const string DefaultPath = "/";
private const string DefaultMethod = "GET";
private const int DefaultStatus = 200;
private const string DefaultConsumer = "Default Consumer";
private const string DefaultProvider = "Default Provider";
/// <summary>
/// Save the mappings as a Pact Json file V2.
/// </summary>
/// <param name="folder">The folder to save the pact file.</param>
/// <param name="filename">The filename for the .json file [optional].</param>
public void SavePact(string folder, string? filename = null)
{
var consumer = Consumer ?? DefaultConsumer;
var provider = Provider ?? DefaultProvider;
filename ??= $"{consumer} - {provider}.json";
var pact = new Pact.Models.V2.Pact
{
Consumer = new Pacticipant { Name = consumer },
Provider = new Pacticipant { Name = provider }
};
foreach (var mapping in MappingModels)
{
var interaction = new Interaction
{
Description = mapping.Description,
ProviderState = mapping.Title,
Request = MapRequest(mapping.Request),
Response = MapResponse(mapping.Response)
};
pact.Interactions.Add(interaction);
}
var bytes = JsonUtils.SerializeAsPactFile(pact);
_settings.FileSystemHandler.WriteFile(folder, filename, bytes);
}
private static Request MapRequest(RequestModel request)
{
string path;
switch (request.Path)
{
case string pathAsString:
path = pathAsString;
break;
case PathModel pathModel:
path = GetPatternAsStringFromMatchers(pathModel.Matchers, DefaultPath);
break;
default:
path = DefaultPath;
break;
}
return new Request
{
Method = request.Methods?.FirstOrDefault() ?? DefaultMethod,
Path = path,
Query = MapQueryParameters(request.Params),
Headers = MapRequestHeaders(request.Headers),
Body = MapBody(request.Body)
};
}
private static Response MapResponse(ResponseModel? response)
{
if (response == null)
{
return new Response();
}
return new Response
{
Status = MapStatusCode(response.StatusCode),
Headers = MapResponseHeaders(response.Headers),
Body = response.BodyAsJson
};
}
private static int MapStatusCode(object? statusCode)
{
if (statusCode is string statusCodeAsString)
{
return int.TryParse(statusCodeAsString, out var statusCodeAsInt) ? statusCodeAsInt : DefaultStatus;
}
if (statusCode != null)
{
// Convert to Int32 because Newtonsoft deserializes an 'object' with a number value to a long.
return Convert.ToInt32(statusCode);
}
return DefaultStatus;
}
private static string? MapQueryParameters(IList<ParamModel>? queryParameters)
{
if (queryParameters == null)
{
return null;
}
var values = queryParameters
.Where(qp => qp.Matchers != null && qp.Matchers.Any() && qp.Matchers[0].Pattern is string)
.Select(param => $"{Uri.EscapeDataString(param.Name)}={Uri.EscapeDataString((string)param.Matchers![0].Pattern)}");
return string.Join("&", values);
}
private static IDictionary<string, string>? MapRequestHeaders(IList<HeaderModel>? headers)
{
if (headers == null)
{
return null;
}
var validHeaders = headers.Where(h => h.Matchers != null && h.Matchers.Any() && h.Matchers[0].Pattern is string);
return validHeaders.ToDictionary(x => x.Name, y => (string)y.Matchers![0].Pattern);
}
private static IDictionary<string, string>? MapResponseHeaders(IDictionary<string, object>? headers)
{
if (headers == null)
{
return null;
}
var validHeaders = headers.Where(h => h.Value is string);
return validHeaders.ToDictionary(x => x.Key, y => (string)y.Value);
}
private static object? MapBody(BodyModel? body)
{
if (body == null || body.Matcher.Name != "JsonMatcher")
{
return null;
}
return body.Matcher.Pattern;
}
private static string GetPatternAsStringFromMatchers(MatcherModel[]? matchers, string defaultValue)
{
if (matchers != null && matchers.Any() && matchers[0].Pattern is string patternAsString)
{
return patternAsString;
}
return defaultValue;
}
}

View File

@@ -30,7 +30,7 @@ public partial class WireMockServer : IWireMockServer
private const int ServerStartDelayInMs = 100;
private readonly WireMockServerSettings _settings;
private readonly IOwinSelfHost _httpServer;
private readonly IOwinSelfHost? _httpServer;
private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
private readonly MappingConverter _mappingConverter;
private readonly MatcherMapper _matcherMapper;
@@ -38,7 +38,7 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc cref="IWireMockServer.IsStarted" />
[PublicAPI]
public bool IsStarted => _httpServer != null && _httpServer.IsStarted;
public bool IsStarted => _httpServer is { IsStarted: true };
/// <inheritdoc />
[PublicAPI]
@@ -54,7 +54,15 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc />
[PublicAPI]
public string Url => Urls?.FirstOrDefault();
public string? Url => Urls?.FirstOrDefault();
/// <inheritdoc />
[PublicAPI]
public string? Consumer { get; private set; }
/// <inheritdoc />
[PublicAPI]
public string? Provider { get; private set; }
/// <summary>
/// Gets the mappings.
@@ -100,9 +108,9 @@ public partial class WireMockServer : IWireMockServer
/// <param name="settings">The WireMockServerSettings.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start([NotNull] WireMockServerSettings settings)
public static WireMockServer Start(WireMockServerSettings settings)
{
Guard.NotNull(settings, nameof(settings));
Guard.NotNull(settings);
return new WireMockServer(settings);
}
@@ -114,7 +122,7 @@ public partial class WireMockServer : IWireMockServer
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="WireMockServer"/>.</returns>
[PublicAPI]
public static WireMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
public static WireMockServer Start(int? port = 0, bool ssl = false)
{
return new WireMockServer(new WireMockServerSettings
{
@@ -239,7 +247,7 @@ public partial class WireMockServer : IWireMockServer
if (settings.CustomCertificateDefined)
{
_options.X509StoreName = settings.CertificateSettings.X509StoreName;
_options.X509StoreName = settings.CertificateSettings!.X509StoreName;
_options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation;
_options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName;
_options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath;
@@ -308,7 +316,7 @@ public partial class WireMockServer : IWireMockServer
Given(Request.Create().WithPath("/*").UsingAnyMethod())
.WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
.AtPriority(1000)
.RespondWith(new DynamicResponseProvider(request => ResponseMessageBuilder.Create("No matching mapping found", 404)));
.RespondWith(new DynamicResponseProvider(_ => ResponseMessageBuilder.Create("No matching mapping found", 404)));
}
/// <inheritdoc cref="IWireMockServer.Reset" />
@@ -373,7 +381,7 @@ public partial class WireMockServer : IWireMockServer
Guard.NotNull(audience, nameof(audience));
#if NETSTANDARD1_3
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
throw new NotSupportedException("AzureADAuthentication is not supported for NETStandard 1.3");
#else
_options.AuthenticationMatcher = new AzureADAuthenticationMatcher(tenant, audience);
#endif
@@ -381,7 +389,7 @@ public partial class WireMockServer : IWireMockServer
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication(string, string)" />
[PublicAPI]
public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
public void SetBasicAuthentication(string username, string password)
{
Guard.NotNull(username, nameof(username));
Guard.NotNull(password, nameof(password));