Skip to content

Commit

Permalink
Fix MappingConverter to support Body with JsonMatcher (#1101)
Browse files Browse the repository at this point in the history
* Fix MappingBuilder for Body

* .

* .

* Fix MappingConverter
  • Loading branch information
StefH committed May 8, 2024
1 parent 9210957 commit e20a90b
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 70 deletions.
26 changes: 11 additions & 15 deletions src/WireMock.Net/Serialization/MappingConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,25 +143,21 @@ public string ToCSharpCode(IMapping mapping, MappingConverterSettings? settings

if (requestMessageBodyMatcher is { Matchers: { } })
{
if (requestMessageBodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
var firstMatcher = requestMessageBodyMatcher.Matchers.FirstOrDefault();

if (firstMatcher is WildcardMatcher wildcardMatcher && wildcardMatcher.GetPatterns().Any())
{
sb.AppendLine($" .WithBody({GetString(wildcardMatcher)})");
}
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
{
sb.AppendLine(@$" .WithBody(new JsonPartialMatcher(
value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())},
ignoreCase: {ToCSharpBooleanLiteral(jsonPartialMatcher.IgnoreCase)},
regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)}
))");
}
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)

if (firstMatcher is JsonMatcher jsonMatcher)
{
sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher(
value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())},
ignoreCase: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.IgnoreCase)},
regex: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.Regex)}
))");
var matcherType = jsonMatcher.GetType().Name;
sb.AppendLine($" .WithBody(new {matcherType}(");
sb.AppendLine($" value: {ConvertToAnonymousObjectDefinition(jsonMatcher.Value, 3)},");
sb.AppendLine($" ignoreCase: {ToCSharpBooleanLiteral(jsonMatcher.IgnoreCase)},");
sb.AppendLine($" regex: {ToCSharpBooleanLiteral(jsonMatcher.Regex)}");
sb.AppendLine(@" ))");
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/WireMock.Net/Server/WireMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,13 @@ private IResponseMessage MappingCodeGet(IRequestMessage requestMessage)

private static MappingConverterType GetMappingConverterType(IRequestMessage requestMessage)
{
var mappingConverterType = MappingConverterType.Server;

if (requestMessage.QueryIgnoreCase?.TryGetValue(nameof(MappingConverterType), out var values) == true &&
Enum.TryParse(values.FirstOrDefault(), true, out MappingConverterType parsed))
{
mappingConverterType = parsed;
return parsed;
}

return mappingConverterType;
return MappingConverterType.Server;
}

private IMapping? FindMappingByGuid(IRequestMessage requestMessage)
Expand Down
10 changes: 5 additions & 5 deletions src/WireMock.Net/Util/CSharpFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace WireMock.Util;

internal static class CSharpFormatter
{
private const string Null = "null";

#region Reserved Keywords
private static readonly HashSet<string> CSharpReservedKeywords = new(new[]
{
Expand Down Expand Up @@ -92,17 +94,15 @@ internal static class CSharpFormatter
"while"
});
#endregion

private const string Null = "null";

public static object ConvertToAnonymousObjectDefinition(object jsonBody)

public static object ConvertToAnonymousObjectDefinition(object jsonBody, int ind = 2)
{
var serializedBody = JsonConvert.SerializeObject(jsonBody);
using var jsonReader = new JsonTextReader(new StringReader(serializedBody));
jsonReader.DateParseHandling = DateParseHandling.None;
var deserializedBody = JObject.Load(jsonReader);

return ConvertJsonToAnonymousObjectDefinition(deserializedBody, 2);
return ConvertJsonToAnonymousObjectDefinition(deserializedBody, ind);
}

public static string ConvertJsonToAnonymousObjectDefinition(JToken token, int ind = 0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,49 @@
var server = WireMockServer.Start();
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post1")
.WithBody(new JsonMatcher(
value: new
{
city = "Amsterdam",
country = "The Netherlands"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
);

server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post2")
.WithBody(new JsonPartialMatcher(
value: new
{
city = "City",
country = "Country"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("1b731398-4a5b-457f-a6e3-d65e541c428f")
.RespondWith(Response.Create()
.WithBody(@"Line1
Some ""value"" in Line2")
);

server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody("1")
Expand All @@ -18,7 +56,7 @@ server
.WithParam("p2", "abc")
.WithHeader("h1", "W/\"234f2q3r\"", true)
)
.WithGuid("1b731398-4a5b-457f-a6e3-d65e541c428f")
.WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd")
.RespondWith(Response.Create()
.WithStatusCode("201")
.WithHeader("hk", "hv")
Expand All @@ -31,7 +69,7 @@ server
.UsingMethod("DELETE")
.WithUrl("https://localhost/test")
)
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
.WithGuid("c9929240-7ae8-4a5d-8ed8-0913479f6eeb")
.RespondWith(Response.Create()
.WithStatusCode(208)
.WithBodyAsJson(new
Expand Down Expand Up @@ -70,20 +108,3 @@ text
})
);

server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/foo3")
.WithBody(new JsonPartialMatcher(
value: "{ a = 1, b = 2 }",
ignoreCase: false,
regex: false
))
)
.WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody(@"Line1
Some ""value"" in Line2")
);

78 changes: 57 additions & 21 deletions test/WireMock.Net.Tests/AdminApi/WireMockAdminApiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ public async Task IWireMockAdminApi_GetMappingAsync_WithProxy_And_ProxyUrlReplac

server.Stop();
}

[Fact]
public async Task IWireMockAdminApi_GetRequestsAsync_Json()
{
Expand Down Expand Up @@ -862,16 +862,45 @@ public async Task IWireMockAdminApi_GetMappingsCode()
var guid2 = Guid.Parse("1b731398-4a5b-457f-a6e3-d65e541c428f");
var guid3 = Guid.Parse("f74fd144-df53-404f-8e35-da22a640bd5f");
var guid4 = Guid.Parse("4126DEC8-470B-4EFF-93BB-C24F83B8B1FD");
var guid5 = Guid.Parse("c9929240-7ae8-4a5d-8ed8-0913479f6eeb");
var server = WireMockServer.StartWithAdminInterface();

server
.Given(
Request.Create()
.WithPath("/users/post1")
.UsingPost()
.WithBody(new JsonMatcher(new
{
city = "Amsterdam",
country = "The Netherlands"
}))
)
.WithGuid(guid1)
.RespondWith(Response.Create());

server
.Given(
Request.Create()
.WithPath("/users/post2")
.UsingPost()
.WithBody(new JsonPartialMatcher(new
{
city = "City",
country = "Country"
}))
)
.WithGuid(guid2)
.RespondWith(Response.Create().WithBody("Line1\r\nSome \"value\" in Line2"));

server
.Given(
Request.Create()
.WithPath("/foo1")
.WithParam("p1", "xyz")
.UsingGet()
)
.WithGuid(guid1)
.WithGuid(guid3)
.RespondWith(
Response.Create()
.WithStatusCode(200)
Expand All @@ -886,7 +915,7 @@ public async Task IWireMockAdminApi_GetMappingsCode()
.WithHeader("h1", "W/\"234f2q3r\"")
.UsingPost()
)
.WithGuid(guid2)
.WithGuid(guid4)
.RespondWith(
Response.Create()
.WithStatusCode("201")
Expand All @@ -901,36 +930,43 @@ public async Task IWireMockAdminApi_GetMappingsCode()
.WithUrl("https://localhost/test")
.UsingDelete()
)
.WithGuid(guid3)
.WithGuid(guid5)
.RespondWith(
Response.Create()
.WithStatusCode(HttpStatusCode.AlreadyReported)
.WithBodyAsJson(new { @as = 1, b = 1.2, d = true, e = false, f = new[] { 1, 2, 3, 4 }, g = new { z1 = 1, z2 = 2, z3 = new[] { "a", "b", "c" }, z4 = new[] { new { a = 1, b = 2 }, new { a = 2, b = 3 } } }, date_field = new DateTime(2023, 05, 08, 11, 20, 19), string_field_with_date = "2021-03-13T21:04:00Z", multiline_text = @"This
.WithBodyAsJson(new
{
@as = 1,
b = 1.2,
d = true,
e = false,
f = new[] { 1, 2, 3, 4 },
g = new
{
z1 = 1,
z2 = 2,
z3 = new[] { "a", "b", "c" },
z4 = new[]
{
new { a = 1, b = 2 },
new { a = 2, b = 3 }
}
},
date_field = new DateTime(2023, 05, 08, 11, 20, 19),
string_field_with_date = "2021-03-13T21:04:00Z",
multiline_text = @"This
is
multiline
text
" })
);

server
.Given(
Request.Create()
.WithPath("/foo3")
.WithBody(new JsonPartialMatcher(new { a = 1, b = 2 }))
.UsingPost()
)
.WithGuid(guid4)
.RespondWith(
Response.Create()
.WithStatusCode(200)
.WithBody("Line1\r\nSome \"value\" in Line2")
"
})
);

// Act
var api = RestClient.For<IWireMockAdminApi>(server.Url);

var mappings = await api.GetMappingsAsync().ConfigureAwait(false);
mappings.Should().HaveCount(4);
mappings.Should().HaveCount(5);

var code = await api.GetMappingsCodeAsync().ConfigureAwait(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,35 @@
BodyDestination: SameAsSource,
Body: { msg: "Hello world!"}
}
},
{
Guid: Guid_2,
UpdatedAt: 2023-01-14 15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post2,
IgnoreCase: false
}
]
},
Methods: [
POST
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
city: Amsterdam,
country: The Netherlands
},
IgnoreCase: false,
Regex: false
}
}
},
Response: {}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
var builder = new MappingBuilder();
builder
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo")
.WithParam("test", "it.Length < 10")
)
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
.RespondWith(Response.Create()
.WithBody("{ msg: \"Hello world!\"}")
);

builder
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post2")
.WithBody(new JsonMatcher(
value: new
{
city = "Amsterdam",
country = "The Netherlands"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931d9b")
.RespondWith(Response.Create()
);

Loading

0 comments on commit e20a90b

Please sign in to comment.