Skip to content

Commit f977b3e

Browse files
authored
Update QueryStringParser to support param with equal but no value (#1253)
* RequestMessageParamMatcher * ? * . * .
1 parent 84e5ba6 commit f977b3e

File tree

4 files changed

+42
-22
lines changed

4 files changed

+42
-22
lines changed

src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,6 @@ private static double CalculateScore(IReadOnlyList<IStringMatcher> matchers, Wir
142142
}
143143
}
144144

145-
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : default;
145+
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : 0;
146146
}
147147
}

src/WireMock.Net/Util/QueryStringParser.cs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ public static bool TryParse(string? queryString, bool caseIgnore, [NotNullWhen(t
2020
{
2121
if (queryString is null)
2222
{
23-
nameValueCollection = default;
23+
nameValueCollection = null;
2424
return false;
2525
}
2626

2727
var parts = queryString!
28-
.Split(new[] { "&" }, StringSplitOptions.RemoveEmptyEntries)
28+
.Split(["&"], StringSplitOptions.RemoveEmptyEntries)
2929
.Select(parameter => parameter.Split('='))
3030
.Distinct();
3131

@@ -50,18 +50,6 @@ public static IDictionary<string, WireMockList<string>> Parse(string? queryStrin
5050

5151
var queryParameterMultipleValueSupport = support ?? QueryParameterMultipleValueSupport.All;
5252

53-
string[] JoinParts(string[] parts)
54-
{
55-
if (parts.Length > 1)
56-
{
57-
return queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Comma) ?
58-
parts[1].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) : // Support "?key=1,2"
59-
new[] { parts[1] };
60-
}
61-
62-
return new string[0];
63-
}
64-
6553
var splitOn = new List<string>();
6654
if (queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Ampersand))
6755
{
@@ -74,8 +62,24 @@ string[] JoinParts(string[] parts)
7462

7563
return queryString!.TrimStart('?')
7664
.Split(splitOn.ToArray(), StringSplitOptions.RemoveEmptyEntries)
77-
.Select(parameter => parameter.Split(new[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))
78-
.GroupBy(parts => parts[0], JoinParts)
79-
.ToDictionary(grouping => grouping.Key, grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode)));
65+
.Select(parameter => new { hasEqualSign = parameter.Contains('='), parts = parameter.Split(['='], 2, StringSplitOptions.RemoveEmptyEntries) })
66+
.GroupBy(x => x.parts[0], y => JoinParts(y.hasEqualSign, y.parts))
67+
.ToDictionary
68+
(
69+
grouping => grouping.Key,
70+
grouping => new WireMockList<string>(grouping.SelectMany(x => x).Select(WebUtility.UrlDecode).OfType<string>())
71+
);
72+
73+
string[] JoinParts(bool hasEqualSign, string[] parts)
74+
{
75+
if (parts.Length > 1)
76+
{
77+
return queryParameterMultipleValueSupport.HasFlag(QueryParameterMultipleValueSupport.Comma) ?
78+
parts[1].Split([","], StringSplitOptions.RemoveEmptyEntries) : // Support "?key=1,2"
79+
[parts[1]];
80+
}
81+
82+
return hasEqualSign ? [string.Empty] : []; // Return empty string if equal sign with no value (#1247)
83+
}
8084
}
8185
}

test/WireMock.Net.Tests/RequestMatchers/RequestMessageParamMatcherTests.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ public void RequestMessageParamMatcher_GetMatchingScore_KeyWith1ValuePresentInUr
4343
Check.That(score).IsEqualTo(0.5d);
4444
}
4545

46+
[Fact]
47+
public void RequestMessageParamMatcher_GetMatchingScore_KeyWithNoValuePresentInUrl_Returns1_0()
48+
{
49+
// Assign
50+
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key="), "GET", "127.0.0.1");
51+
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, "");
52+
53+
// Act
54+
var result = new RequestMatchResult();
55+
var score = matcher.GetMatchingScore(requestMessage, result);
56+
57+
// Assert
58+
Check.That(score).IsEqualTo(1.0d);
59+
}
60+
4661
[Fact]
4762
public void RequestMessageParamMatcher_GetMatchingScore_KeyWith3ValuesPresentInUrl_And_With1ExactStringWith2Patterns_Returns0_66()
4863
{

test/WireMock.Net.Tests/Util/QueryStringParserTests.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public void Parse_With1ParamNoValueWithEqualSign()
148148

149149
// Assert
150150
result.Count.Should().Be(1);
151-
result["empty"].Should().Equal(new WireMockList<string>());
151+
result["empty"].Should().Equal(new WireMockList<string>(""));
152152
}
153153

154154
[Fact]
@@ -354,18 +354,19 @@ public void Parse_With1ParamContainingComma_Using_QueryParameterMultipleValueSup
354354
public void Parse_WithComplex()
355355
{
356356
// Assign
357-
string query = "?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22";
357+
string query = "?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22&x";
358358

359359
// Act
360360
var result = QueryStringParser.Parse(query);
361361

362362
// Assert
363-
result.Count.Should().Be(6);
363+
result.Count.Should().Be(7);
364364
result["q"].Should().Equal(new WireMockList<string>("energy edge"));
365365
result["rls"].Should().Equal(new WireMockList<string>("com.microsoft:en-au"));
366366
result["ie"].Should().Equal(new WireMockList<string>("UTF-8"));
367367
result["oe"].Should().Equal(new WireMockList<string>("UTF-8"));
368-
result["startIndex"].Should().Equal(new WireMockList<string>());
368+
result["startIndex"].Should().Equal(new WireMockList<string>(""));
369369
result["startPage"].Should().Equal(new WireMockList<string>("1\""));
370+
result["x"].Should().Equal(new WireMockList<string>());
370371
}
371372
}

0 commit comments

Comments
 (0)