mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-06-12 09:44:30 +02:00
Partial
This commit is contained in:
@@ -1,6 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<startup>
|
<startup>
|
||||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||||
</startup>
|
</startup>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
@@ -20,62 +21,64 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
|
|
||||||
server.AllowPartialMapping();
|
server.AllowPartialMapping();
|
||||||
|
|
||||||
//server
|
server
|
||||||
// .Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
|
.Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
|
||||||
// .AtPriority(4)
|
.AtPriority(4)
|
||||||
// .RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
// .WithStatusCode(200)
|
.WithStatusCode(200)
|
||||||
// .WithHeader("Content-Type", "application/json")
|
.WithHeader("Content-Type", "application/json")
|
||||||
// .WithBody(@"{ ""result"": ""Contains x with FUNC 200""}"));
|
.WithBody(@"{ ""result"": ""Contains x with FUNC 200""}"));
|
||||||
|
|
||||||
//server
|
|
||||||
// .Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e")))
|
|
||||||
// .RespondWith(Response.Create()
|
|
||||||
// .WithStatusCode(201)
|
|
||||||
// .WithHeader("Content-Type", "application/json")
|
|
||||||
// .WithBody(@"{ ""result"": ""data posted with FUNC 201""}"));
|
|
||||||
|
|
||||||
//server
|
|
||||||
// .Given(Request.Create().WithPath("/data", "/ax").UsingPost().WithHeader("Content-Type", "application/json*"))
|
|
||||||
// .RespondWith(Response.Create()
|
|
||||||
// .WithStatusCode(201)
|
|
||||||
// .WithHeader("Content-Type", "application/json")
|
|
||||||
// .WithBody(@"{ ""result"": ""data posted with 201""}"));
|
|
||||||
|
|
||||||
//server
|
|
||||||
// .Given(Request.Create().WithPath("/json").UsingPost().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]")))
|
|
||||||
// .RespondWith(Response.Create()
|
|
||||||
// .WithStatusCode(201)
|
|
||||||
// .WithHeader("Content-Type", "application/json")
|
|
||||||
// .WithBody(@"{ ""result"": ""json posted with 201""}"));
|
|
||||||
|
|
||||||
//server
|
|
||||||
// .Given(Request.Create().WithPath("/json2").UsingPost().WithBody("x"))
|
|
||||||
// .RespondWith(Response.Create()
|
|
||||||
// .WithStatusCode(201)
|
|
||||||
// .WithHeader("Content-Type", "application/json")
|
|
||||||
// .WithBody(@"{ ""result"": ""json posted with x - 201""}"));
|
|
||||||
|
|
||||||
//server
|
|
||||||
// .Given(Request.Create().WithPath("/data").UsingDelete())
|
|
||||||
// .RespondWith(Response.Create()
|
|
||||||
// .WithStatusCode(200)
|
|
||||||
// .WithHeader("Content-Type", "application/json")
|
|
||||||
// .WithBody(@"{ ""result"": ""data deleted with 200""}"));
|
|
||||||
|
|
||||||
//server
|
|
||||||
// .Given(Request.Create().WithPath("/nobody").UsingGet())
|
|
||||||
// .RespondWith(Response.Create().WithDelay(TimeSpan.FromSeconds(1))
|
|
||||||
// .WithStatusCode(200));
|
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/partial").UsingGet().WithHeader("p", "p"))
|
.Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e")))
|
||||||
|
.AtPriority(999)
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(201)
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBody(@"{ ""result"": ""data posted with FUNC 201""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/data", "/ax").UsingPost().WithHeader("Content-Type", "application/json*"))
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(201)
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBody(@"{ ""result"": ""data posted with 201""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/json").UsingPost().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]")))
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(201)
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBody(@"{ ""result"": ""json posted with 201""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/json2").UsingPost().WithBody("x"))
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(201)
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBody(@"{ ""result"": ""json posted with x - 201""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/data").UsingDelete())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(200)
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBody(@"{ ""result"": ""data deleted with 200""}"));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/nobody").UsingGet())
|
||||||
|
.RespondWith(Response.Create().WithDelay(TimeSpan.FromSeconds(1))
|
||||||
|
.WithStatusCode(200));
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/partial").UsingPost().WithBody(new SimMetricsMatcher("cat")))
|
||||||
.RespondWith(Response.Create().WithStatusCode(200).WithBody("partial = 200"));
|
.RespondWith(Response.Create().WithStatusCode(200).WithBody("partial = 200"));
|
||||||
|
|
||||||
// http://localhost:8080/any/any?start=1000&stop=1&stop=2
|
// http://localhost:8080/any/any?start=1000&stop=1&stop=2
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/*").UsingGet())
|
.Given(Request.Create().WithPath("/*").UsingGet())
|
||||||
.WithGuid(Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05"))
|
.WithGuid(Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05"))
|
||||||
|
.AtPriority(server.Mappings.Count() + 1)
|
||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithStatusCode(200)
|
.WithStatusCode(200)
|
||||||
.WithHeader("Content-Type", "application/json")
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
|||||||
@@ -37,6 +37,10 @@
|
|||||||
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="SimMetrics.Net, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\packages\SimMetrics.Net.1.0.1.0\lib\net45\SimMetrics.Net.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="WireMock.Net">
|
<Reference Include="WireMock.Net">
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||||
|
<package id="SimMetrics.Net" version="1.0.1.0" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -31,6 +31,14 @@ namespace WireMock.Admin.Requests
|
|||||||
/// </value>
|
/// </value>
|
||||||
public LogResponseModel Response { get; set; }
|
public LogResponseModel Response { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the mapping unique identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The mapping unique identifier.
|
||||||
|
/// </value>
|
||||||
|
public Guid? MappingGuid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the request match result.
|
/// Gets or sets the request match result.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -39,5 +39,13 @@ namespace WireMock.Logging
|
|||||||
/// The request match result.
|
/// The request match result.
|
||||||
/// </value>
|
/// </value>
|
||||||
public RequestMatchResult RequestMatchResult { get; set; }
|
public RequestMatchResult RequestMatchResult { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the mapping unique identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The mapping unique identifier.
|
||||||
|
/// </value>
|
||||||
|
public Guid? MappingGuid { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ namespace WireMock.Matchers
|
|||||||
/// <returns>Name</returns>
|
/// <returns>Name</returns>
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return $"SimMetricsMatcher ({_simMetricType})";
|
return $"SimMetricsMatcher.{_simMetricType}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using SimMetrics.Net;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Admin.Requests;
|
using WireMock.Admin.Requests;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
@@ -11,6 +12,7 @@ using WireMock.Matchers;
|
|||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Server
|
namespace WireMock.Server
|
||||||
{
|
{
|
||||||
@@ -203,11 +205,12 @@ namespace WireMock.Server
|
|||||||
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
||||||
Headers = logEntry.ResponseMessage.Headers
|
Headers = logEntry.ResponseMessage.Headers
|
||||||
},
|
},
|
||||||
RequestMatchResult = new LogRequestMatchModel
|
MappingGuid = logEntry.MappingGuid,
|
||||||
|
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
|
||||||
{
|
{
|
||||||
MatchScore = logEntry.RequestMatchResult.MatchScore,
|
MatchScore = logEntry.RequestMatchResult.MatchScore,
|
||||||
Total = logEntry.RequestMatchResult.Total
|
Total = logEntry.RequestMatchResult.Total
|
||||||
}
|
} : null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,26 +225,31 @@ namespace WireMock.Server
|
|||||||
private IRequestBuilder InitRequestBuilder(MappingModel mappingModel)
|
private IRequestBuilder InitRequestBuilder(MappingModel mappingModel)
|
||||||
{
|
{
|
||||||
IRequestBuilder requestBuilder = Request.Create();
|
IRequestBuilder requestBuilder = Request.Create();
|
||||||
string path = mappingModel.Request.Path as string;
|
|
||||||
if (path != null)
|
if (mappingModel.Request.Path != null)
|
||||||
requestBuilder = requestBuilder.WithPath(path);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
JToken pathToken = (JToken)mappingModel.Request.Path;
|
string path = mappingModel.Request.Path as string;
|
||||||
PathModel pathModel = pathToken.ToObject<PathModel>();
|
if (path != null)
|
||||||
if (pathModel?.Matchers != null)
|
requestBuilder = requestBuilder.WithPath(path);
|
||||||
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(Map).ToArray());
|
else
|
||||||
|
{
|
||||||
|
var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(mappingModel.Request.Path);
|
||||||
|
if (pathModel?.Matchers != null)
|
||||||
|
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(Map).ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string url = mappingModel.Request.Url as string;
|
if (mappingModel.Request.Url != null)
|
||||||
if (url != null)
|
|
||||||
requestBuilder = requestBuilder.WithUrl(url);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
JToken urlToken = (JToken)mappingModel.Request.Url;
|
string url = mappingModel.Request.Url as string;
|
||||||
UrlModel urlModel = urlToken.ToObject<UrlModel>();
|
if (url != null)
|
||||||
if (urlModel?.Matchers != null)
|
requestBuilder = requestBuilder.WithUrl(url);
|
||||||
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(Map).ToArray());
|
else
|
||||||
|
{
|
||||||
|
var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(mappingModel.Request.Url);
|
||||||
|
if (urlModel?.Matchers != null)
|
||||||
|
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(Map).ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mappingModel.Request.Methods != null)
|
if (mappingModel.Request.Methods != null)
|
||||||
@@ -412,7 +420,11 @@ namespace WireMock.Server
|
|||||||
if (matcher == null)
|
if (matcher == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
switch (matcher.Name)
|
var parts = matcher.Name.Split('.');
|
||||||
|
string matcherName = parts[0];
|
||||||
|
string matcherType = parts.Length > 1 ? parts[1] : null;
|
||||||
|
|
||||||
|
switch (matcherName)
|
||||||
{
|
{
|
||||||
case "RegexMatcher":
|
case "RegexMatcher":
|
||||||
return new RegexMatcher(matcher.Pattern);
|
return new RegexMatcher(matcher.Pattern);
|
||||||
@@ -423,8 +435,18 @@ namespace WireMock.Server
|
|||||||
case "XPathMatcher":
|
case "XPathMatcher":
|
||||||
return new XPathMatcher(matcher.Pattern);
|
return new XPathMatcher(matcher.Pattern);
|
||||||
|
|
||||||
default:
|
case "WildcardMatcher":
|
||||||
return new WildcardMatcher(matcher.Pattern, matcher.IgnoreCase == true);
|
return new WildcardMatcher(matcher.Pattern, matcher.IgnoreCase == true);
|
||||||
|
|
||||||
|
case "SimMetricsMatcher":
|
||||||
|
SimMetricType type = SimMetricType.Levenstein;
|
||||||
|
if (!string.IsNullOrEmpty(matcherType) && !Enum.TryParse(matcherType, out type))
|
||||||
|
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||||
|
|
||||||
|
return new SimMetricsMatcher(matcher.Pattern, type);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ namespace WireMock.Server
|
|||||||
var request = _requestMapper.Map(ctx.Request);
|
var request = _requestMapper.Map(ctx.Request);
|
||||||
|
|
||||||
ResponseMessage response = null;
|
ResponseMessage response = null;
|
||||||
|
Mapping targetMapping = null;
|
||||||
RequestMatchResult requestMatchResult = null;
|
RequestMatchResult requestMatchResult = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -338,15 +339,19 @@ namespace WireMock.Server
|
|||||||
.Select(m => new { Mapping = m, MatchResult = m.IsRequestHandled(request) })
|
.Select(m => new { Mapping = m, MatchResult = m.IsRequestHandled(request) })
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
Mapping targetMapping;
|
|
||||||
if (_allowPartialMapping)
|
if (_allowPartialMapping)
|
||||||
{
|
{
|
||||||
var orderedMappings = possibleMatchingMappings
|
var orderedMappings = possibleMatchingMappings
|
||||||
.OrderBy(m => m.Mapping.Priority)
|
.Where(pm =>
|
||||||
.ThenBy(m => m.MatchResult)
|
(pm.Mapping.Provider is DynamicResponseProvider && pm.MatchResult.IsPerfectMatch) ||
|
||||||
|
!(pm.Mapping.Provider is DynamicResponseProvider)
|
||||||
|
)
|
||||||
|
.OrderBy(m => m.MatchResult)
|
||||||
|
.ThenBy(m => m.Mapping.Priority)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var bestPartialMatch = orderedMappings.FirstOrDefault();
|
var bestPartialMatch = orderedMappings.FirstOrDefault();
|
||||||
|
|
||||||
targetMapping = bestPartialMatch?.Mapping;
|
targetMapping = bestPartialMatch?.Mapping;
|
||||||
requestMatchResult = bestPartialMatch?.MatchResult;
|
requestMatchResult = bestPartialMatch?.MatchResult;
|
||||||
}
|
}
|
||||||
@@ -388,6 +393,7 @@ namespace WireMock.Server
|
|||||||
Guid = Guid.NewGuid(),
|
Guid = Guid.NewGuid(),
|
||||||
RequestMessage = request,
|
RequestMessage = request,
|
||||||
ResponseMessage = response,
|
ResponseMessage = response,
|
||||||
|
MappingGuid = targetMapping?.Guid,
|
||||||
RequestMatchResult = requestMatchResult
|
RequestMatchResult = requestMatchResult
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
internal static class JsonUtils
|
||||||
|
{
|
||||||
|
public static T ParseJTokenToObject<T>(object value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
return default(T);
|
||||||
|
|
||||||
|
JToken token = value as JToken;
|
||||||
|
if (token == null)
|
||||||
|
return default(T);
|
||||||
|
|
||||||
|
return token.ToObject<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user