mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-22 00:59:02 +01:00
Fixed JsonPathMatcher to match nested objects (#966)
* Fixed JsonPathMatcher to match nested objects * fix * . * 100%
This commit is contained in:
@@ -121,6 +121,32 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
|
||||
private double IsMatch(JToken jToken)
|
||||
{
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
|
||||
var array = ConvertJTokenToJArrayIfNeeded(jToken);
|
||||
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => array.SelectToken(pattern.GetPattern())?.Any() == true).ToArray(), MatchOperator);
|
||||
}
|
||||
|
||||
// https://github.com/WireMock-Net/WireMock.Net/issues/965
|
||||
// https://stackoverflow.com/questions/66922188/newtonsoft-jsonpath-with-c-sharp-syntax
|
||||
// Filtering using SelectToken() isn't guaranteed to work for objects inside objects -- only objects inside arrays.
|
||||
// So this code checks if it's an JArray, if it's not an array, construct a new JArray.
|
||||
private static JToken ConvertJTokenToJArrayIfNeeded(JToken jToken)
|
||||
{
|
||||
if (jToken.Count() == 1)
|
||||
{
|
||||
var property = jToken.First();
|
||||
var item = property.First();
|
||||
if (item is JArray)
|
||||
{
|
||||
return jToken;
|
||||
}
|
||||
|
||||
return new JObject
|
||||
{
|
||||
[property.Path] = new JArray(item)
|
||||
};
|
||||
}
|
||||
|
||||
return jToken;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_GetName()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("X");
|
||||
|
||||
// Act
|
||||
@@ -24,7 +24,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_GetPatterns()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("X");
|
||||
|
||||
// Act
|
||||
@@ -37,7 +37,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_ByteArray()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var bytes = EmptyArray<byte>.Value;
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
@@ -51,7 +51,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_NullString()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
string? s = null;
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
@@ -65,7 +65,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_NullObject()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
object? o = null;
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
@@ -79,7 +79,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_String_Exception_Mismatch()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("xxx");
|
||||
|
||||
// Act
|
||||
@@ -92,7 +92,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
@@ -105,7 +105,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_AnonymousObject()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
@@ -115,10 +115,51 @@ public class JsonPathMatcherTests
|
||||
Check.That(match).IsEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_AnonymousObject_WithNestedObject()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new { things = new { name = "x" } });
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_String_WithNestedObject()
|
||||
{
|
||||
// Arrange
|
||||
var json = "{ \"things\": { \"name\": \"x\" } }";
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(json);
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsNoMatch_String_WithNestedObject()
|
||||
{
|
||||
// Arrange
|
||||
var json = "{ \"things\": { \"name\": \"y\" } }";
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(json);
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_JObject()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
string[] patterns = { "$..[?(@.Id == 1)]" };
|
||||
var matcher = new JsonPathMatcher(patterns);
|
||||
|
||||
@@ -137,7 +178,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_JObject_Parsed()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
@@ -150,7 +191,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_RejectOnMatch()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
|
||||
Reference in New Issue
Block a user