diff --git a/Test/Flurl.Test/Http/TestingTests.cs b/Test/Flurl.Test/Http/TestingTests.cs
index 137447a0..c055757d 100644
--- a/Test/Flurl.Test/Http/TestingTests.cs
+++ b/Test/Flurl.Test/Http/TestingTests.cs
@@ -138,6 +138,29 @@ public async Task can_respond_based_on_query_params() {
Assert.AreEqual("query param conditions met!", await "http://api.com?x=1&y=2&z=3&c=yes".GetStringAsync());
}
+ [Test] // #596
+ public async Task url_patterns_ignore_query_when_not_specified() {
+ HttpTest.ForCallsTo("http://api.com/1").RespondWith("one");
+ HttpTest.ForCallsTo("http://api.com/2").WithAnyQueryParam().RespondWith("two");
+ HttpTest.ForCallsTo("http://api.com/3").WithoutQueryParams().RespondWith("three");
+
+ Assert.AreEqual("one", await "http://api.com/1".GetStringAsync());
+ Assert.AreEqual("one", await "http://api.com/1?x=foo&y=bar".GetStringAsync());
+
+ Assert.AreEqual("", await "http://api.com/2".GetStringAsync());
+ Assert.AreEqual("two", await "http://api.com/2?x=foo&y=bar".GetStringAsync());
+
+ Assert.AreEqual("three", await "http://api.com/3".GetStringAsync());
+ Assert.AreEqual("", await "http://api.com/3?x=foo&y=bar".GetStringAsync());
+
+ HttpTest.ShouldHaveCalled("http://api.com/1").Times(2);
+ HttpTest.ShouldHaveCalled("http://api.com/1").WithAnyQueryParam().Times(1);
+ HttpTest.ShouldHaveCalled("http://api.com/1").WithoutQueryParams().Times(1);
+ HttpTest.ShouldHaveCalled("http://api.com/1?x=foo").Times(1);
+ HttpTest.ShouldHaveCalled("http://api.com/1?x=foo").WithQueryParam("y").Times(1);
+ HttpTest.ShouldHaveCalled("http://api.com/1?x=foo").WithQueryParam("y", "bar").Times(1);
+ }
+
[Test]
public async Task can_respond_based_on_headers() {
HttpTest
diff --git a/src/Flurl.Http/Testing/FilteredHttpTestSetup.cs b/src/Flurl.Http/Testing/FilteredHttpTestSetup.cs
index d32f20fc..935fb637 100644
--- a/src/Flurl.Http/Testing/FilteredHttpTestSetup.cs
+++ b/src/Flurl.Http/Testing/FilteredHttpTestSetup.cs
@@ -21,7 +21,7 @@ public class FilteredHttpTestSetup : HttpTestSetup
/// URL(s) or URL pattern(s) that this HttpTestSetup applies to. Can contain * wildcard.
public FilteredHttpTestSetup(TestFlurlHttpSettings settings, params string[] urlPatterns) : base(settings) {
if (urlPatterns.Any())
- With(call => urlPatterns.Any(p => Util.MatchesPattern(call.Request.Url, p)));
+ With(call => urlPatterns.Any(p => Util.MatchesUrlPattern(call.Request.Url, p)));
}
///
diff --git a/src/Flurl.Http/Testing/HttpCallAssertion.cs b/src/Flurl.Http/Testing/HttpCallAssertion.cs
index cdfdb2a7..e96b0f6a 100644
--- a/src/Flurl.Http/Testing/HttpCallAssertion.cs
+++ b/src/Flurl.Http/Testing/HttpCallAssertion.cs
@@ -68,7 +68,7 @@ public HttpCallAssertion Without(Func match, string descrip = n
///
/// Can contain * wildcard.
public HttpCallAssertion WithUrlPattern(string urlPattern) {
- return With(c => Util.MatchesPattern(c.Request.Url, urlPattern), $"URL pattern {urlPattern}");
+ return With(c => Util.MatchesUrlPattern(c.Request.Url, urlPattern), $"URL pattern {urlPattern}");
}
///
diff --git a/src/Flurl.Http/Testing/Util.cs b/src/Flurl.Http/Testing/Util.cs
index 6cbad816..12c2af83 100644
--- a/src/Flurl.Http/Testing/Util.cs
+++ b/src/Flurl.Http/Testing/Util.cs
@@ -90,6 +90,23 @@ private static bool MatchesValueOrPattern(object valueToMatch, object value) {
return valueToMatch?.ToInvariantString() == value?.ToInvariantString();
}
+ ///
+ /// same as MatchesPattern, but doesn't require trailing * to ignore query string
+ ///
+ internal static bool MatchesUrlPattern(string url, string pattern) {
+ if (MatchesPattern(url, pattern))
+ return true;
+ if (pattern.OrdinalEndsWith("*"))
+ return false;
+ if (pattern.OrdinalContains("?"))
+ return MatchesPattern(url, pattern + "&*");
+ else
+ return MatchesPattern(url, pattern + "?*");
+ }
+
+ ///
+ /// match simple patterns with * wildcard
+ ///
internal static bool MatchesPattern(string textToCheck, string pattern) {
// avoid regex'ing in simple cases
if (string.IsNullOrEmpty(pattern) || pattern == "*") return true;