mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-25 18:41:01 +01:00
Add FormUrlEncodedMatcher (#1147)
* FormUrlEncodedMatcher * . * Fix * new * support wildcard
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
Guid: Guid_1,
|
||||
Guid: 41372914-1838-4c67-916b-b9aacdd096ce,
|
||||
UpdatedAt: 2023-01-14 15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
Guid: Guid_2,
|
||||
Guid: 98fae52e-76df-47d9-876f-2ee32e931002,
|
||||
UpdatedAt: 2023-01-14 15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
@@ -61,5 +61,77 @@
|
||||
}
|
||||
},
|
||||
Response: {}
|
||||
},
|
||||
{
|
||||
Guid: 98fae52e-76df-47d9-876f-2ee32e931003,
|
||||
UpdatedAt: 2023-01-14 15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: /form-urlencoded,
|
||||
IgnoreCase: false
|
||||
}
|
||||
]
|
||||
},
|
||||
Methods: [
|
||||
POST
|
||||
],
|
||||
Headers: [
|
||||
{
|
||||
Name: Content-Type,
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: application/x-www-form-urlencoded,
|
||||
IgnoreCase: true
|
||||
}
|
||||
],
|
||||
IgnoreCase: true
|
||||
}
|
||||
],
|
||||
Body: {
|
||||
Matcher: {
|
||||
Name: FormUrlEncodedMatcher,
|
||||
Patterns: [
|
||||
name=John Doe,
|
||||
email=johndoe@example.com
|
||||
],
|
||||
IgnoreCase: false,
|
||||
MatchOperator: Or
|
||||
}
|
||||
}
|
||||
},
|
||||
Response: {}
|
||||
},
|
||||
{
|
||||
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
|
||||
UpdatedAt: 2023-01-14 15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: /users/post1,
|
||||
IgnoreCase: false
|
||||
}
|
||||
]
|
||||
},
|
||||
Methods: [
|
||||
POST
|
||||
],
|
||||
Body: {
|
||||
Matcher: {
|
||||
Name: JsonMatcher,
|
||||
Pattern: {
|
||||
Request: Hello?
|
||||
},
|
||||
IgnoreCase: false,
|
||||
Regex: false
|
||||
}
|
||||
}
|
||||
},
|
||||
Response: {}
|
||||
}
|
||||
]
|
||||
@@ -24,7 +24,35 @@ builder
|
||||
regex: false
|
||||
))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931d9b")
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931002")
|
||||
.RespondWith(Response.Create()
|
||||
);
|
||||
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath("/form-urlencoded")
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
|
||||
.WithBody("name=John Doe")
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931003")
|
||||
.RespondWith(Response.Create()
|
||||
);
|
||||
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath("/users/post1")
|
||||
.WithBody(new JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
Request = "Hello?"
|
||||
},
|
||||
ignoreCase: false,
|
||||
regex: false
|
||||
))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
|
||||
.RespondWith(Response.Create()
|
||||
);
|
||||
|
||||
|
||||
@@ -24,7 +24,35 @@ server
|
||||
regex: false
|
||||
))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931d9b")
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931002")
|
||||
.RespondWith(Response.Create()
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath("/form-urlencoded")
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
|
||||
.WithBody("name=John Doe")
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931003")
|
||||
.RespondWith(Response.Create()
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath("/users/post1")
|
||||
.WithBody(new JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
Request = "Hello?"
|
||||
},
|
||||
ignoreCase: false,
|
||||
regex: false
|
||||
))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
|
||||
.RespondWith(Response.Create()
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
Guid: Guid_1,
|
||||
Guid: 41372914-1838-4c67-916b-b9aacdd096ce,
|
||||
UpdatedAt: 2023-01-14T15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
@@ -33,7 +33,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
Guid: Guid_2,
|
||||
Guid: 98fae52e-76df-47d9-876f-2ee32e931002,
|
||||
UpdatedAt: 2023-01-14T15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
@@ -60,5 +60,75 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Guid: 98fae52e-76df-47d9-876f-2ee32e931003,
|
||||
UpdatedAt: 2023-01-14T15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: /form-urlencoded,
|
||||
IgnoreCase: false
|
||||
}
|
||||
]
|
||||
},
|
||||
Methods: [
|
||||
POST
|
||||
],
|
||||
Headers: [
|
||||
{
|
||||
Name: Content-Type,
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: application/x-www-form-urlencoded,
|
||||
IgnoreCase: true
|
||||
}
|
||||
],
|
||||
IgnoreCase: true
|
||||
}
|
||||
],
|
||||
Body: {
|
||||
Matcher: {
|
||||
Name: FormUrlEncodedMatcher,
|
||||
Patterns: [
|
||||
name=John Doe,
|
||||
email=johndoe@example.com
|
||||
],
|
||||
IgnoreCase: false,
|
||||
MatchOperator: Or
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
|
||||
UpdatedAt: 2023-01-14T15:16:17,
|
||||
Request: {
|
||||
Path: {
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: /users/post1,
|
||||
IgnoreCase: false
|
||||
}
|
||||
]
|
||||
},
|
||||
Methods: [
|
||||
POST
|
||||
],
|
||||
Body: {
|
||||
Matcher: {
|
||||
Name: JsonMatcher,
|
||||
Pattern: {
|
||||
Request: Hello?
|
||||
},
|
||||
IgnoreCase: false,
|
||||
Regex: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -30,7 +30,6 @@ public class MappingBuilderTests
|
||||
VerifySettings.Init();
|
||||
}
|
||||
|
||||
private static readonly Guid NewGuid = new("98fae52e-76df-47d9-876f-2ee32e931d9b");
|
||||
private const string MappingGuid = "41372914-1838-4c67-916b-b9aacdd096ce";
|
||||
private static readonly DateTime UtcNow = new(2023, 1, 14, 15, 16, 17);
|
||||
|
||||
@@ -43,7 +42,8 @@ public class MappingBuilderTests
|
||||
_fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
||||
|
||||
var guidUtilsMock = new Mock<IGuidUtils>();
|
||||
guidUtilsMock.Setup(g => g.NewGuid()).Returns(NewGuid);
|
||||
var startGuid = 1000;
|
||||
guidUtilsMock.Setup(g => g.NewGuid()).Returns(() => new Guid($"98fae52e-76df-47d9-876f-2ee32e93{startGuid++}"));
|
||||
|
||||
var dateTimeUtilsMock = new Mock<IDateTimeUtils>();
|
||||
dateTimeUtilsMock.SetupGet(d => d.UtcNow).Returns(UtcNow);
|
||||
@@ -95,6 +95,13 @@ public class MappingBuilderTests
|
||||
country = "The Netherlands"
|
||||
}))
|
||||
).RespondWith(Response.Create());
|
||||
|
||||
_sut.Given(Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/form-urlencoded")
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||
.WithBody(new FormUrlEncodedMatcher(["name=John Doe", "email=johndoe@example.com"]))
|
||||
).RespondWith(Response.Create());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -104,7 +111,7 @@ public class MappingBuilderTests
|
||||
var mappings = _sut.GetMappings();
|
||||
|
||||
// Verify
|
||||
return Verifier.Verify(mappings, VerifySettings);
|
||||
return Verifier.Verify(mappings, VerifySettings).DontScrubGuids();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -114,7 +121,7 @@ public class MappingBuilderTests
|
||||
var json = _sut.ToJson();
|
||||
|
||||
// Verify
|
||||
return Verifier.VerifyJson(json, VerifySettings);
|
||||
return Verifier.VerifyJson(json, VerifySettings).DontScrubGuids();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -124,7 +131,7 @@ public class MappingBuilderTests
|
||||
var code = _sut.ToCSharpCode(MappingConverterType.Server);
|
||||
|
||||
// Verify
|
||||
return Verifier.Verify(code, VerifySettings);
|
||||
return Verifier.Verify(code, VerifySettings).DontScrubGuids();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -134,7 +141,7 @@ public class MappingBuilderTests
|
||||
var code = _sut.ToCSharpCode(MappingConverterType.Builder);
|
||||
|
||||
// Verify
|
||||
return Verifier.Verify(code, VerifySettings);
|
||||
return Verifier.Verify(code, VerifySettings).DontScrubGuids();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -183,9 +190,9 @@ public class MappingBuilderTests
|
||||
_sut.SaveMappingsToFolder(null);
|
||||
|
||||
// Verify
|
||||
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(2));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(2));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(2));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(4));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(4));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(4));
|
||||
_fileSystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
@@ -201,8 +208,8 @@ public class MappingBuilderTests
|
||||
|
||||
// Verify
|
||||
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never);
|
||||
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(2));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(2));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(4));
|
||||
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(4));
|
||||
_fileSystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using AnyOfTypes;
|
||||
using FluentAssertions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Matchers;
|
||||
|
||||
public class FormUrlEncodedMatcherTest
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("*=*")]
|
||||
[InlineData("name=John Doe")]
|
||||
[InlineData("name=*")]
|
||||
[InlineData("*=John Doe")]
|
||||
[InlineData("email=johndoe@example.com")]
|
||||
[InlineData("email=*")]
|
||||
[InlineData("*=johndoe@example.com")]
|
||||
[InlineData("name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData("name=John Doe", "email=*")]
|
||||
[InlineData("name=*", "email=*")]
|
||||
[InlineData("*=John Doe", "*=johndoe@example.com")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch(params string[] patterns)
|
||||
{
|
||||
// Arrange
|
||||
var content = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
});
|
||||
var contentAsString = await content.ReadAsStringAsync();
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.Select(p => new AnyOf<string, StringPattern>(p)).ToArray());
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
|
||||
// Assert
|
||||
score.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, "name=John Doe")]
|
||||
[InlineData(false, "name=*")]
|
||||
[InlineData(false, "*=John Doe")]
|
||||
[InlineData(false, "email=johndoe@example.com")]
|
||||
[InlineData(false, "email=*")]
|
||||
[InlineData(false, "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=*")]
|
||||
[InlineData(true, "name=*", "email=*")]
|
||||
[InlineData(true, "*=John Doe", "*=johndoe@example.com")]
|
||||
[InlineData(true, "*=*")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_And(bool expected, params string[] patterns)
|
||||
{
|
||||
// Arrange
|
||||
var content = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
});
|
||||
var contentAsString = await content.ReadAsStringAsync();
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.Select(p => new AnyOf<string, StringPattern>(p)).ToArray(), true, MatchOperator.And);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
|
||||
// Assert
|
||||
score.Should().Be(expected);
|
||||
}
|
||||
}
|
||||
@@ -225,5 +225,63 @@ public partial class WireMockServerTests
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFormUrlEncodedMatcher()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new FormUrlEncodedMatcher(["email=johndoe@example.com", "name=John Doe"]);
|
||||
var server = WireMockServer.Start();
|
||||
server.Given(
|
||||
Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/foo")
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||
.WithBody(matcher)
|
||||
)
|
||||
.RespondWith(
|
||||
Response.Create()
|
||||
);
|
||||
|
||||
server.Given(
|
||||
Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/bar")
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||
.WithBody(matcher)
|
||||
)
|
||||
.RespondWith(
|
||||
Response.Create()
|
||||
);
|
||||
|
||||
// Act 1
|
||||
var contentOrdered = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
});
|
||||
var responseOrdered = await new HttpClient()
|
||||
.PostAsync($"{server.Url}/foo", contentOrdered)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// Assert 1
|
||||
responseOrdered.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
|
||||
// Act 2
|
||||
var contentUnordered = new FormUrlEncodedContent(new[]
|
||||
{
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com"),
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
});
|
||||
var responseUnordered = await new HttpClient()
|
||||
.PostAsync($"{server.Url}/bar", contentUnordered)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// Assert 2
|
||||
responseUnordered.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user