mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-01 06:33:11 +02:00
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:
@@ -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>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
167
src/WireMock.Net/Server/WireMockServer.Pact.cs
Normal file
167
src/WireMock.Net/Server/WireMockServer.Pact.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user