diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs index 36d790092..f5e130475 100644 --- a/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs +++ b/src/WireMock.Net/Matchers/Request/RequestMessageBodyMatcher.cs @@ -104,7 +104,7 @@ public RequestMessageBodyMatcher(Func func) /// Initializes a new instance of the class. /// /// The function. - public RequestMessageBodyMatcher(Func func) + public RequestMessageBodyMatcher(Func func) { BodyDataFunc = Guard.NotNull(func); } diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs index 949ed7de0..41311838c 100644 --- a/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs +++ b/src/WireMock.Net/Matchers/Request/RequestMessageParamMatcher.cs @@ -53,7 +53,8 @@ public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, boo /// The key. /// Defines if the key should be matched using case-ignore. /// The values. - public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, string[]? values) : this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, ignoreCase, false, MatchOperator.And, value)).Cast().ToArray()) + public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, params string[]? values) : + this(matchBehaviour, key, ignoreCase, values?.Select(value => new ExactMatcher(matchBehaviour, ignoreCase, false, MatchOperator.And, value)).Cast().ToArray()) { } @@ -64,7 +65,7 @@ public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, boo /// The key. /// Defines if the key should be matched using case-ignore. /// The matchers. - public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, IStringMatcher[]? matchers) + public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, string key, bool ignoreCase, params IStringMatcher[]? matchers) { MatchBehaviour = matchBehaviour; Key = Guard.NotNull(key); @@ -95,7 +96,7 @@ private double IsMatch(IRequestMessage requestMessage) return MatchScores.ToScore(requestMessage.Query != null && Funcs.Any(f => f(requestMessage.Query))); } - var valuesPresentInRequestMessage = ((RequestMessage)requestMessage).GetParameter(Key!, IgnoreCase ?? false); + var valuesPresentInRequestMessage = ((RequestMessage)requestMessage).GetParameter(Key, IgnoreCase ?? false); if (valuesPresentInRequestMessage == null) { // Key is not present at all, just return Mismatch diff --git a/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs b/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs index 29afe592e..ccd00f436 100644 --- a/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs +++ b/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs @@ -68,7 +68,7 @@ public async Task MapAsync(IRequest request, IWireMockMiddleware body = await BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false); } - return new RequestMessage(urlDetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow }; + return new RequestMessage(options, urlDetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow }; } private static (UrlDetails UrlDetails, string ClientIP) ParseRequest(IRequest request) diff --git a/test/WireMock.Net.Tests/RequestMatchers/RequestMessageParamMatcherTests.cs b/test/WireMock.Net.Tests/RequestMatchers/RequestMessageParamMatcherTests.cs index 048040e6c..58a929b1f 100644 --- a/test/WireMock.Net.Tests/RequestMatchers/RequestMessageParamMatcherTests.cs +++ b/test/WireMock.Net.Tests/RequestMatchers/RequestMessageParamMatcherTests.cs @@ -1,7 +1,10 @@ +using FluentAssertions; using NFluent; using WireMock.Matchers; using WireMock.Matchers.Request; using WireMock.Models; +using WireMock.Owin; +using WireMock.Types; using Xunit; namespace WireMock.Net.Tests.RequestMatchers @@ -172,5 +175,25 @@ public void RequestMessageParamMatcher_GetMatchingScore_KeyWithValuePresentInUrl // Assert Check.That(score).IsEqualTo(1.0d); } + + // Issue #849 + [Fact] + public void RequestMessageParamMatcher_With1ParamContainingComma_Using_QueryParameterMultipleValueSupport_NoComma() + { + // Assign + var options = new WireMockMiddlewareOptions + { + QueryParameterMultipleValueSupport = QueryParameterMultipleValueSupport.NoComma + }; + var requestMessage = new RequestMessage(options, new UrlDetails("http://localhost?query=SELECT id, value FROM table WHERE id = 1&test=42"), "GET", "127.0.0.1"); + var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "query", false, "SELECT id, value FROM table WHERE id = 1"); + + // Act + var result = new RequestMatchResult(); + double score = matcher.GetMatchingScore(requestMessage, result); + + // Assert + score.Should().Be(1.0); + } } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Util/QueryStringParserTests.cs b/test/WireMock.Net.Tests/Util/QueryStringParserTests.cs index c273c297f..7ef71388f 100644 --- a/test/WireMock.Net.Tests/Util/QueryStringParserTests.cs +++ b/test/WireMock.Net.Tests/Util/QueryStringParserTests.cs @@ -274,7 +274,7 @@ public void Parse_WithMultipleParamWithSameKey() } [Fact] - public void Parse_With1ParamContainingSpacesAndEqualSign() + public void Parse_With1ParamContainingSpacesSingleQuoteAndEqualSign() { // Assign string query = "?q=SELECT Id from User where username='user@gmail.com'"; @@ -287,6 +287,22 @@ public void Parse_With1ParamContainingSpacesAndEqualSign() result["q"].Should().Equal(new WireMockList("SELECT Id from User where username='user@gmail.com'")); } + // Issue #849 + [Fact] + public void Parse_With1ParamContainingComma_Using_QueryParameterMultipleValueSupport_NoComma() + { + // Assign + string query = "?query=SELECT id, value FROM table WHERE id = 1&test=42"; + + // Act + var result = QueryStringParser.Parse(query, QueryParameterMultipleValueSupport.NoComma); + + // Assert + result.Count.Should().Be(2); + result["query"].Should().Equal(new WireMockList("SELECT id, value FROM table WHERE id = 1")); + result["test"].Should().Equal(new WireMockList("42")); + } + [Fact] public void Parse_WithComplex() { diff --git a/test/WireMock.Net.Tests/WireMockServerTests.WithParam.cs b/test/WireMock.Net.Tests/WireMockServerTests.WithParam.cs new file mode 100644 index 000000000..f4d9fcf16 --- /dev/null +++ b/test/WireMock.Net.Tests/WireMockServerTests.WithParam.cs @@ -0,0 +1,46 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using WireMock.RequestBuilders; +using WireMock.ResponseBuilders; +using WireMock.Server; +using WireMock.Settings; +using WireMock.Types; +using Xunit; + +namespace WireMock.Net.Tests; + +public partial class WireMockServerTests +{ + [Theory] + [InlineData("SELECT id, value FROM table WHERE id = 1")] + [InlineData("select id, name, value from table where id in (1, 2, 3, 4, 5)")] + public async Task WireMockServer_WithParam_QueryParameterMultipleValueSupport_NoComma_Should_Ignore_Comma(string queryValue) + { + // Arrange + var settings = new WireMockServerSettings + { + QueryParameterMultipleValueSupport = QueryParameterMultipleValueSupport.NoComma + }; + var server = WireMockServer.Start(settings); + server.Given( + Request.Create() + .UsingGet() + .WithPath("/foo") + .WithParam("query", queryValue) + ) + .RespondWith( + Response.Create().WithStatusCode(200) + ); + + // Act + var requestUri = new Uri($"http://localhost:{server.Port}/foo?query={queryValue}"); + var response = await server.CreateClient().GetAsync(requestUri).ConfigureAwait(false); + + // Assert + response.StatusCode.Should().Be(HttpStatusCode.OK); + + server.Stop(); + } +} \ No newline at end of file