Update QueryStringParser to support param with equal but no value (#1253)

* RequestMessageParamMatcher

* ?

* .

* .
This commit is contained in:
Stef Heyenrath
2025-02-13 18:09:18 +01:00
committed by GitHub
parent 84e5ba6dce
commit f977b3eb86
4 changed files with 42 additions and 22 deletions

View File

@@ -142,6 +142,6 @@ public class RequestMessageParamMatcher : IRequestMatcher
}
}
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : default;
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : 0;
}
}

View File

@@ -20,12 +20,12 @@ internal static class QueryStringParser
{
if (queryString is null)
{
nameValueCollection = default;
nameValueCollection = null;
return false;
}
var parts = queryString!
.Split(new[] { "&" }, StringSplitOptions.RemoveEmptyEntries)
.Split(["&"], StringSplitOptions.RemoveEmptyEntries)
.Select(parameter => parameter.Split('='))
.Distinct();
@@ -50,18 +50,6 @@ internal static class QueryStringParser
var queryParameterMultipleValueSupport = support ?? QueryParameterMultipleValueSupport.All;
string[] JoinParts(string[] parts)
{
if (parts.Length > 1)
{
return queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Comma) ?
parts[1].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) : // Support "?key=1,2"
new[] { parts[1] };
}
return new string[0];
}
var splitOn = new List<string>();
if (queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Ampersand))
{
@@ -74,8 +62,24 @@ internal static class QueryStringParser
return queryString!.TrimStart('?')
.Split(splitOn.ToArray(), StringSplitOptions.RemoveEmptyEntries)
.Select(parameter => parameter.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))
.GroupBy(parts => parts[0], JoinParts)
.ToDictionary(grouping => grouping.Key, grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode)));
.Select(parameter => new { hasEqualSign = parameter.Contains('='), parts = parameter.Split(['='], 2, StringSplitOptions.RemoveEmptyEntries) })
.GroupBy(x => x.parts[0], y => JoinParts(y.hasEqualSign, y.parts))
.ToDictionary
(
grouping => grouping.Key,
grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode).OfType<string>())
);
string[] JoinParts(bool hasEqualSign, string[] parts)
{
if (parts.Length > 1)
{
return queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Comma) ?
parts[1].Split([","], StringSplitOptions.RemoveEmptyEntries) : // Support "?key=1,2"
[parts[1]];
}
return hasEqualSign ? [string.Empty] : []; // Return empty string if equal sign with no value (#1247)
}
}
}

View File

@@ -43,6 +43,21 @@ public class RequestMessageParamMatcherTests
Check.That(score).IsEqualTo(0.5d);
}
[Fact]
public void RequestMessageParamMatcher_GetMatchingScore_KeyWithNoValuePresentInUrl_Returns1_0()
{
// Assign
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key="), "GET", "127.0.0.1");
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, "");
// Act
var result = new RequestMatchResult();
var score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageParamMatcher_GetMatchingScore_KeyWith3ValuesPresentInUrl_And_With1ExactStringWith2Patterns_Returns0_66()
{

View File

@@ -148,7 +148,7 @@ public class QueryStringParserTests
// Assert
result.Count.Should().Be(1);
result["empty"].Should().Equal(new WireMockList<string>());
result["empty"].Should().Equal(new WireMockList<string>(""));
}
[Fact]
@@ -354,18 +354,19 @@ public class QueryStringParserTests
public void Parse_WithComplex()
{
// Assign
string query = "?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22";
string query = "?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22&x";
// Act
var result = QueryStringParser.Parse(query);
// Assert
result.Count.Should().Be(6);
result.Count.Should().Be(7);
result["q"].Should().Equal(new WireMockList<string>("energy edge"));
result["rls"].Should().Equal(new WireMockList<string>("com.microsoft:en-au"));
result["ie"].Should().Equal(new WireMockList<string>("UTF-8"));
result["oe"].Should().Equal(new WireMockList<string>("UTF-8"));
result["startIndex"].Should().Equal(new WireMockList<string>());
result["startIndex"].Should().Equal(new WireMockList<string>(""));
result["startPage"].Should().Equal(new WireMockList<string>("1\""));
result["x"].Should().Equal(new WireMockList<string>());
}
}