Add more tests for JmesPathMatchers and StringUtils.ParseMatchOperator (#1009)

* Add more tests for JmesPathMatchers and StringUtils.ParseMatchOperator

* .

* prio
This commit is contained in:
Stef Heyenrath
2023-10-16 17:13:52 +02:00
committed by GitHub
parent f7cd4b100e
commit 2f29d80336
8 changed files with 185 additions and 23 deletions

View File

@@ -35,11 +35,7 @@ internal class MappingMatcher : IMappingMatcher
{
var nextState = GetNextState(mapping);
var mappingMatcherResult = new MappingMatcherResult
{
Mapping = mapping,
RequestMatchResult = mapping.GetRequestMatchResult(request, nextState)
};
var mappingMatcherResult = new MappingMatcherResult(mapping, mapping.GetRequestMatchResult(request, nextState));
var exceptions = mappingMatcherResult.RequestMatchResult.MatchDetails
.Where(md => md.Exception != null)
@@ -66,7 +62,10 @@ internal class MappingMatcher : IMappingMatcher
var partialMappings = possibleMappings
.Where(pm => (pm.Mapping.IsAdminInterface && pm.RequestMatchResult.IsPerfectMatch) || !pm.Mapping.IsAdminInterface)
.OrderBy(m => m.RequestMatchResult).ThenBy(m => m.Mapping.Priority).ThenByDescending(m => m.Mapping.UpdatedAt)
.OrderBy(m => m.RequestMatchResult)
.ThenBy(m => m.RequestMatchResult.TotalNumber)
.ThenBy(m => m.Mapping.Priority)
.ThenByDescending(m => m.Mapping.UpdatedAt)
.ToList();
var partialMatch = partialMappings.FirstOrDefault(pm => pm.RequestMatchResult.AverageTotalScore > 0.0);

View File

@@ -1,10 +1,17 @@
using Stef.Validation;
using WireMock.Matchers.Request;
namespace WireMock.Owin;
internal class MappingMatcherResult
{
public IMapping Mapping { get; set; }
public IMapping Mapping { get; }
public IRequestMatchResult RequestMatchResult { get; set; }
public IRequestMatchResult RequestMatchResult { get; }
public MappingMatcherResult(IMapping mapping, IRequestMatchResult requestMatchResult)
{
Mapping = Guard.NotNull(mapping);
RequestMatchResult = Guard.NotNull(requestMatchResult);
}
}

View File

@@ -61,7 +61,7 @@ public interface IRespondWithAProvider
/// <summary>
/// Define the priority for this mapping.
/// </summary>
/// <param name="priority">The priority.</param>
/// <param name="priority">The priority. (A lower value means a higher priority.)</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
IRespondWithAProvider AtPriority(int priority);

View File

@@ -16,6 +16,7 @@ using WireMock.Admin.Requests;
using WireMock.Settings;
using FluentAssertions;
using WireMock.Handlers;
using WireMock.Matchers.Request;
using WireMock.ResponseBuilders;
using WireMock.RequestBuilders;
#if NET452
@@ -43,6 +44,7 @@ public class WireMockMiddlewareTests
private readonly Mock<IOwinResponseMapper> _responseMapperMock;
private readonly Mock<IMappingMatcher> _matcherMock;
private readonly Mock<IMapping> _mappingMock;
private readonly Mock<IRequestMatchResult> _requestMatchResultMock;
private readonly Mock<IContext> _contextMock;
private readonly WireMockMiddleware _sut;
@@ -72,12 +74,16 @@ public class WireMockMiddlewareTests
_matcherMock = new Mock<IMappingMatcher>();
_matcherMock.SetupAllProperties();
_matcherMock.Setup(m => m.FindBestMatch(It.IsAny<RequestMessage>())).Returns((new MappingMatcherResult(), new MappingMatcherResult()));
// _matcherMock.Setup(m => m.FindBestMatch(It.IsAny<RequestMessage>())).Returns((new MappingMatcherResult(), new MappingMatcherResult()));
_contextMock = new Mock<IContext>();
_mappingMock = new Mock<IMapping>();
_requestMatchResultMock = new Mock<IRequestMatchResult>();
_requestMatchResultMock.Setup(r => r.TotalNumber).Returns(1);
_requestMatchResultMock.Setup(r => r.MatchDetails).Returns(new List<MatchDetail>());
_sut = new WireMockMiddleware(
null,
_optionsMock.Object,
@@ -133,7 +139,7 @@ public class WireMockMiddlewareTests
_optionsMock.SetupGet(o => o.AuthenticationMatcher).Returns(new ExactMatcher());
_mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true);
var result = new MappingMatcherResult { Mapping = _mappingMock.Object };
var result = new MappingMatcherResult(_mappingMock.Object, _requestMatchResultMock.Object);
_matcherMock.Setup(m => m.FindBestMatch(It.IsAny<RequestMessage>())).Returns((result, result));
// Act
@@ -156,7 +162,7 @@ public class WireMockMiddlewareTests
_optionsMock.SetupGet(o => o.AuthenticationMatcher).Returns(new ExactMatcher());
_mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true);
var result = new MappingMatcherResult { Mapping = _mappingMock.Object };
var result = new MappingMatcherResult(_mappingMock.Object, _requestMatchResultMock.Object);
_matcherMock.Setup(m => m.FindBestMatch(It.IsAny<RequestMessage>())).Returns((result, result));
// Act
@@ -216,7 +222,7 @@ public class WireMockMiddlewareTests
var requestBuilder = Request.Create().UsingAnyMethod();
_mappingMock.SetupGet(m => m.RequestMatcher).Returns(requestBuilder);
var result = new MappingMatcherResult { Mapping = _mappingMock.Object };
var result = new MappingMatcherResult(_mappingMock.Object, _requestMatchResultMock.Object);
_matcherMock.Setup(m => m.FindBestMatch(It.IsAny<RequestMessage>())).Returns((result, result));
// Act
@@ -270,7 +276,7 @@ public class WireMockMiddlewareTests
var requestBuilder = Request.Create().UsingAnyMethod();
_mappingMock.SetupGet(m => m.RequestMatcher).Returns(requestBuilder);
var result = new MappingMatcherResult { Mapping = _mappingMock.Object };
var result = new MappingMatcherResult (_mappingMock.Object, _requestMatchResultMock.Object);
_matcherMock.Setup(m => m.FindBestMatch(It.IsAny<RequestMessage>())).Returns((result, result));
// Act

View File

@@ -300,6 +300,31 @@ public class RequestMessageBodyMatcherTests
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageBodyMatcher_GetMatchingScore_BodyAsJson_JmesPathMatchers()
{
// Arrange
var body = new BodyData
{
BodyAsJson = new { requestId = "1", value = "A" },
DetectedBodyType = BodyType.Json
};
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
var jmesMatcher1 = new JmesPathMatcher("requestId == '1'");
var jmesMatcher2 = new JmesPathMatcher("value == 'A'");
var bodyMatcher = new RequestMessageBodyMatcher(MatchOperator.And, jmesMatcher1, jmesMatcher2);
// Act
var result = new RequestMatchResult();
double score = bodyMatcher.GetMatchingScore(requestMessage, result);
// Assert
score.Should().Be(MatchScores.Perfect);
}
[Theory]
[InlineData(null, 0.0)]
[InlineData(new byte[0], 0.0)]

View File

@@ -1,4 +1,5 @@
using FluentAssertions;
using WireMock.Matchers;
using WireMock.Util;
using Xunit;
@@ -6,13 +7,39 @@ namespace WireMock.Net.Tests.Util;
public class StringUtilsTests
{
[Theory]
[InlineData("And", MatchOperator.And)]
[InlineData("Or", MatchOperator.Or)]
public void ParseMatchOperator_ShouldReturnCorrectEnumValue_WhenValidStringIsProvided(string value, MatchOperator expected)
{
// Arrange & Act
var result = StringUtils.ParseMatchOperator(value);
// Assert
result.Should().Be(expected);
}
[Theory]
[InlineData(null, MatchOperator.Or)]
[InlineData("", MatchOperator.Or)]
[InlineData("and", MatchOperator.Or)]
[InlineData("InvalidValue", MatchOperator.Or)]
public void ParseMatchOperator_ShouldReturnDefaultEnumValue_WhenInvalidOrNullStringIsProvided(string? value, MatchOperator expected)
{
// Arrange & Act
var result = StringUtils.ParseMatchOperator(value);
// Assert
result.Should().Be(expected);
}
[Theory]
[InlineData("'s")]
[InlineData("\"s")]
public void StringUtils_TryParseQuotedString_With_UnexpectedUnclosedString_Returns_False(string input)
{
// Act
bool valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
var valid = StringUtils.TryParseQuotedString(input, out _, out _);
// Assert
valid.Should().BeFalse();
@@ -25,7 +52,7 @@ public class StringUtilsTests
public void StringUtils_TryParseQuotedString_With_InvalidStringLength_Returns_False(string input)
{
// Act
bool valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
var valid = StringUtils.TryParseQuotedString(input, out _, out _);
// Assert
valid.Should().BeFalse();
@@ -37,7 +64,7 @@ public class StringUtilsTests
public void StringUtils_TryParseQuotedString_With_InvalidStringQuoteCharacter_Returns_False(string input)
{
// Act
bool valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
var valid = StringUtils.TryParseQuotedString(input, out _, out _);
// Assert
valid.Should().BeFalse();
@@ -47,10 +74,10 @@ public class StringUtilsTests
public void StringUtils_TryParseQuotedString_With_UnexpectedUnrecognizedEscapeSequence_Returns_False()
{
// Arrange
string input = new string(new[] { '"', '\\', 'u', '?', '"' });
var input = new string(new[] { '"', '\\', 'u', '?', '"' });
// Act
bool valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
var valid = StringUtils.TryParseQuotedString(input, out _, out _);
// Assert
valid.Should().BeFalse();
@@ -64,7 +91,7 @@ public class StringUtilsTests
public void StringUtils_TryParseQuotedString_SingleQuotedString(string input, string expectedResult)
{
// Act
bool valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
var valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
// Assert
valid.Should().BeTrue();
@@ -93,7 +120,7 @@ public class StringUtilsTests
public void StringUtils_TryParseQuotedString_DoubleQuotedString(string input, string expectedResult)
{
// Act
bool valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
var valid = StringUtils.TryParseQuotedString(input, out var result, out var quote);
// Assert
valid.Should().BeTrue();

View File

@@ -3,6 +3,8 @@
<PropertyGroup>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net461;netcoreapp3.1;net6.0;net7.0</TargetFrameworks>
<LangVersion>11</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<DebugType>full</DebugType>
<AssemblyName>WireMock.Net.Tests</AssemblyName>

View File

@@ -1,9 +1,8 @@
#if !NET452
//using System;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
//using System.Net.Http.Json;
using System.Threading.Tasks;
using FluentAssertions;
using WireMock.Matchers;
@@ -21,6 +20,103 @@ public partial class WireMockServerTests
public string? Hi { get; set; }
}
[Fact]
public async Task WireMockServer_WithBodyAsJson_Using_PostAsJsonAsync_And_MultipleJmesPathMatchers_ShouldMatch()
{
// Arrange
var server = WireMockServer.Start();
server.Given(
Request.Create()
.WithPath("/a")
.WithBody(
new IMatcher[]
{
new JmesPathMatcher("requestId == '1'"),
new JmesPathMatcher("value == 'A'")
},
MatchOperator.And
)
.UsingPost()
)
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.OK));
server.Given(
Request.Create()
.WithPath("/a")
.WithBody(
new IMatcher[]
{
new JmesPathMatcher("requestId == '2'"),
new JmesPathMatcher("value == 'A'")
},
MatchOperator.And
)
.UsingPost()
)
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.Moved));
// Act
var requestUri = new Uri($"http://localhost:{server.Port}/a");
var json = new { requestId = "1", value = "A" };
var response = await server.CreateClient().PostAsJsonAsync(requestUri, json).ConfigureAwait(false);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
server.Stop();
}
[Fact]
public async Task WireMockServer_WithBodyAsJson_Using_PostAsJsonAsync_And_MultipleJmesPathMatchers_ShouldMatch_BestMatching()
{
// Arrange
var server = WireMockServer.Start();
server.Given(
Request.Create()
.WithPath("/a")
.WithBody(
new IMatcher[]
{
new JmesPathMatcher("extra == 'X'"),
new JmesPathMatcher("requestId == '1'"),
new JmesPathMatcher("value == 'A'")
},
MatchOperator.And
)
.UsingPost()
)
.AtPriority(1) // Higher priority
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.OK));
server.Given(
Request.Create()
.WithPath("/a")
.WithBody(
new IMatcher[]
{
new JmesPathMatcher("requestId == '1'"),
new JmesPathMatcher("value == 'A'")
},
MatchOperator.And
)
.UsingPost()
)
.AtPriority(2)
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.Moved));
// Act
var requestUri = new Uri($"http://localhost:{server.Port}/a");
var json = new { extra = "X", requestId = "1", value = "A" };
var response = await server.CreateClient().PostAsJsonAsync(requestUri, json).ConfigureAwait(false);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
server.Stop();
}
[Fact]
public async Task WireMockServer_WithBodyAsJson_Using_PostAsJsonAsync_And_WildcardMatcher_ShouldMatch()
{