mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-01 07:03:29 +02:00
Merge branch 'stef_fix_174_jsonpathmatcher'
This commit is contained in:
@@ -6,16 +6,12 @@
|
|||||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Remove="__admin\mappings\826aff7c-6208-4a3c-923d-575248907db4.json" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="..\WireMock.Net.ConsoleApplication\MainApp.cs" Link="MainApp.cs" />
|
<Compile Include="..\WireMock.Net.ConsoleApplication\MainApp.cs" Link="MainApp.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
<Content Include="__admin\mappings\*.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -3,14 +3,7 @@
|
|||||||
"Title": "",
|
"Title": "",
|
||||||
"Priority": 0,
|
"Priority": 0,
|
||||||
"Request": {
|
"Request": {
|
||||||
"Path": {
|
"Path": "/proxy-google-test-post",
|
||||||
"Matchers": [
|
|
||||||
{
|
|
||||||
"Name": "WildcardMatcher",
|
|
||||||
"Pattern": "/proxy-google-test-post"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Methods": [
|
"Methods": [
|
||||||
"post"
|
"post"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
|
||||||
|
"Priority": 4,
|
||||||
|
"Request": {
|
||||||
|
"Path": {},
|
||||||
|
"Methods": [
|
||||||
|
"get"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Response": {
|
||||||
|
"StatusCode": 200,
|
||||||
|
"BodyDestination": "SameAsSource",
|
||||||
|
"Body": "NO PATH OR URL",
|
||||||
|
"UseTransformer": false,
|
||||||
|
"Headers": {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,14 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
|
|
||||||
server.AllowPartialMapping();
|
server.AllowPartialMapping();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
|
||||||
|
.AtPriority(4)
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(200)
|
||||||
|
.WithHeader("Content-Type", "application/json")
|
||||||
|
.WithBody(@"{ ""result"": ""Contains x with FUNC 200""}"));
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create()
|
.Given(Request.Create()
|
||||||
.UsingGet()
|
.UsingGet()
|
||||||
@@ -53,7 +61,7 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
.WithPath("/proxy-execute-keep-alive")
|
.WithPath("/proxy-execute-keep-alive")
|
||||||
)
|
)
|
||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithProxy(new ProxyAndRecordSettings { Url = "http://localhost:9999", BlackListedHeaders = new [] { "Keep-Alive" } })
|
.WithProxy(new ProxyAndRecordSettings { Url = "http://localhost:9999", BlackListedHeaders = new[] { "Keep-Alive" } })
|
||||||
.WithHeader("Keep-Alive-Test", "stef")
|
.WithHeader("Keep-Alive-Test", "stef")
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -144,8 +152,10 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/file_rel").UsingGet())
|
.Given(Request.Create().WithPath("/file_rel").UsingGet())
|
||||||
|
.WithGuid("0000aaaa-fcf4-4256-a0d3-1c76e4862947")
|
||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithBodyFromFile("Program.cs", false)
|
.WithHeader("Content-Type", "application/xml")
|
||||||
|
.WithBodyFromFile("WireMock.Net.xml", false)
|
||||||
);
|
);
|
||||||
|
|
||||||
server
|
server
|
||||||
@@ -176,14 +186,6 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
.WithStatusCode(200)
|
.WithStatusCode(200)
|
||||||
.WithBody("hi"));
|
.WithBody("hi"));
|
||||||
|
|
||||||
server
|
|
||||||
.Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
|
|
||||||
.AtPriority(4)
|
|
||||||
.RespondWith(Response.Create()
|
|
||||||
.WithStatusCode(200)
|
|
||||||
.WithHeader("Content-Type", "application/json")
|
|
||||||
.WithBody(@"{ ""result"": ""Contains x with FUNC 200""}"));
|
|
||||||
|
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e")))
|
.Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e")))
|
||||||
.AtPriority(999)
|
.AtPriority(999)
|
||||||
@@ -284,7 +286,7 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
.Given(Request.Create().WithPath("/jsonpathtestTokenJson").UsingPost())
|
.Given(Request.Create().WithPath("/jsonpathtestTokenJson").UsingPost())
|
||||||
.RespondWith(Response.Create()
|
.RespondWith(Response.Create()
|
||||||
.WithHeader("Content-Type", "application/json")
|
.WithHeader("Content-Type", "application/json")
|
||||||
.WithBodyAsJson(new { status = "OK", url = "{{request.url}}", transformed = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" } )
|
.WithBodyAsJson(new { status = "OK", url = "{{request.url}}", transformed = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" })
|
||||||
.WithTransformer()
|
.WithTransformer()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,9 @@
|
|||||||
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<None Include="__admin\mappings\873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj">
|
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj">
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
|
||||||
|
"Priority": 4,
|
||||||
|
"Request": {
|
||||||
|
"Path": {},
|
||||||
|
"Methods": [
|
||||||
|
"get"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Response": {
|
||||||
|
"StatusCode": 200,
|
||||||
|
"BodyDestination": "SameAsSource",
|
||||||
|
"Body": "NO PATH OR URL",
|
||||||
|
"UseTransformer": false,
|
||||||
|
"Headers": {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -63,7 +63,9 @@ namespace WireMock.Matchers
|
|||||||
public double IsMatch(object input)
|
public double IsMatch(object input)
|
||||||
{
|
{
|
||||||
double match = MatchScores.Mismatch;
|
double match = MatchScores.Mismatch;
|
||||||
if (input != null)
|
|
||||||
|
// When input is null or byte[], return Mismatch.
|
||||||
|
if (input != null && !(input is byte[]))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -65,7 +65,9 @@ namespace WireMock.Matchers
|
|||||||
public double IsMatch(object input)
|
public double IsMatch(object input)
|
||||||
{
|
{
|
||||||
bool match = false;
|
bool match = false;
|
||||||
if (input != null)
|
|
||||||
|
// When input is null or byte[], return Mismatch.
|
||||||
|
if (input != null && !(input is byte[]))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace WireMock.Serialization
|
|||||||
string matcherName = parts[0];
|
string matcherName = parts[0];
|
||||||
string matcherType = parts.Length > 1 ? parts[1] : null;
|
string matcherType = parts.Length > 1 ? parts[1] : null;
|
||||||
|
|
||||||
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new [] { matcher.Pattern as string };
|
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new[] { matcher.Pattern as string };
|
||||||
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
||||||
|
|
||||||
switch (matcherName)
|
switch (matcherName)
|
||||||
@@ -39,7 +39,7 @@ namespace WireMock.Serialization
|
|||||||
return new JsonPathMatcher(matchBehaviour, stringPatterns);
|
return new JsonPathMatcher(matchBehaviour, stringPatterns);
|
||||||
|
|
||||||
case "XPathMatcher":
|
case "XPathMatcher":
|
||||||
return new XPathMatcher(matchBehaviour, (string) matcher.Pattern);
|
return new XPathMatcher(matchBehaviour, (string)matcher.Pattern);
|
||||||
|
|
||||||
case "WildcardMatcher":
|
case "WildcardMatcher":
|
||||||
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
|
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
|
||||||
@@ -51,7 +51,7 @@ namespace WireMock.Serialization
|
|||||||
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SimMetricsMatcher(matchBehaviour, (string) matcher.Pattern, type);
|
return new SimMetricsMatcher(matchBehaviour, (string)matcher.Pattern, type);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
||||||
|
|||||||
@@ -121,7 +121,15 @@ namespace WireMock.Server
|
|||||||
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
||||||
{
|
{
|
||||||
_logger.Info("Reading Static MappingFile : '{0}'", filename);
|
_logger.Info("Reading Static MappingFile : '{0}'", filename);
|
||||||
ReadStaticMappingAndAddOrUpdate(filename);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ReadStaticMappingAndAddOrUpdate(filename);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_logger.Error("Static MappingFile : '{0}' could not be read. This file will be skipped.", filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,9 +324,9 @@ namespace WireMock.Server
|
|||||||
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
||||||
|
|
||||||
var mappingModel = DeserializeObject<MappingModel>(requestMessage);
|
var mappingModel = DeserializeObject<MappingModel>(requestMessage);
|
||||||
DeserializeAndAddOrUpdateMapping(mappingModel, guid);
|
Guid? guidFromPut = DeserializeAndAddOrUpdateMapping(mappingModel, guid);
|
||||||
|
|
||||||
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guid);
|
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResponseMessage MappingDelete(RequestMessage requestMessage)
|
private ResponseMessage MappingDelete(RequestMessage requestMessage)
|
||||||
@@ -401,13 +409,18 @@ namespace WireMock.Server
|
|||||||
return ResponseMessageBuilder.Create("Mapping added", 201, guid);
|
return ResponseMessageBuilder.Create("Mapping added", 201, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Guid DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
|
private Guid? DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
|
||||||
{
|
{
|
||||||
Check.NotNull(mappingModel, nameof(mappingModel));
|
Check.NotNull(mappingModel, nameof(mappingModel));
|
||||||
Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
|
Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
|
||||||
Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
|
Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
|
||||||
|
|
||||||
var requestBuilder = InitRequestBuilder(mappingModel.Request);
|
var requestBuilder = InitRequestBuilder(mappingModel.Request, true);
|
||||||
|
if (requestBuilder == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var responseBuilder = InitResponseBuilder(mappingModel.Response);
|
var responseBuilder = InitResponseBuilder(mappingModel.Response);
|
||||||
|
|
||||||
var respondProvider = Given(requestBuilder);
|
var respondProvider = Given(requestBuilder);
|
||||||
@@ -511,7 +524,7 @@ namespace WireMock.Server
|
|||||||
{
|
{
|
||||||
var requestModel = DeserializeObject<RequestModel>(requestMessage);
|
var requestModel = DeserializeObject<RequestModel>(requestMessage);
|
||||||
|
|
||||||
var request = (Request)InitRequestBuilder(requestModel);
|
var request = (Request)InitRequestBuilder(requestModel, false);
|
||||||
|
|
||||||
var dict = new Dictionary<LogEntry, RequestMatchResult>();
|
var dict = new Dictionary<LogEntry, RequestMatchResult>();
|
||||||
foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))
|
foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))
|
||||||
@@ -551,7 +564,7 @@ namespace WireMock.Server
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
|
private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
|
||||||
{
|
{
|
||||||
IRequestBuilder requestBuilder = Request.Create();
|
IRequestBuilder requestBuilder = Request.Create();
|
||||||
|
|
||||||
@@ -571,11 +584,13 @@ namespace WireMock.Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pathOrUrlmatchersValid = false;
|
||||||
if (requestModel.Path != null)
|
if (requestModel.Path != null)
|
||||||
{
|
{
|
||||||
if (requestModel.Path is string path)
|
if (requestModel.Path is string path)
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithPath(path);
|
requestBuilder = requestBuilder.WithPath(path);
|
||||||
|
pathOrUrlmatchersValid = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -583,15 +598,16 @@ namespace WireMock.Server
|
|||||||
if (pathModel?.Matchers != null)
|
if (pathModel?.Matchers != null)
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
|
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
|
||||||
|
pathOrUrlmatchersValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (requestModel.Url != null)
|
||||||
if (requestModel.Url != null)
|
|
||||||
{
|
{
|
||||||
if (requestModel.Url is string url)
|
if (requestModel.Url is string url)
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithUrl(url);
|
requestBuilder = requestBuilder.WithUrl(url);
|
||||||
|
pathOrUrlmatchersValid = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -599,10 +615,17 @@ namespace WireMock.Server
|
|||||||
if (urlModel?.Matchers != null)
|
if (urlModel?.Matchers != null)
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
|
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
|
||||||
|
pathOrUrlmatchersValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pathOrUrlRequired && !pathOrUrlmatchersValid)
|
||||||
|
{
|
||||||
|
_logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (requestModel.Methods != null)
|
if (requestModel.Methods != null)
|
||||||
{
|
{
|
||||||
requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);
|
requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);
|
||||||
|
|||||||
@@ -33,6 +33,20 @@ namespace WireMock.Net.Tests.Matchers
|
|||||||
Check.That(value).Equals("{}");
|
Check.That(value).Equals("{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void JsonMatcher_IsMatch_ByteArray()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
var bytes = new byte[0];
|
||||||
|
var matcher = new JsonMatcher("");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
double match = matcher.IsMatch(bytes);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(match).IsEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void JsonMatcher_IsMatch_NullString()
|
public void JsonMatcher_IsMatch_NullString()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -33,6 +33,20 @@ namespace WireMock.Net.Tests.Matchers
|
|||||||
Check.That(patterns).ContainsExactly("X");
|
Check.That(patterns).ContainsExactly("X");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void JsonPathMatcher_IsMatch_ByteArray()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
var bytes = new byte[0];
|
||||||
|
var matcher = new JsonPathMatcher("");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
double match = matcher.IsMatch(bytes);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(match).IsEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_NullString()
|
public void JsonPathMatcher_IsMatch_NullString()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user