Skip to content

Commit

Permalink
Merge branch 'master' into stef-1071-split
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Jun 8, 2024
2 parents c857266 + 8b03307 commit 3c44bce
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 34 deletions.
29 changes: 27 additions & 2 deletions examples/WireMock.Net.Client/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ class Program
{
static async Task Main(string[] args)
{
// Start WireMock.Net tool with Admin interface
// dotnet-wiremock --StartAdminInterface

// Create an implementation of the IWireMockAdminApi and pass in the base URL for the API.
var api = RestClient.For<IWireMockAdminApi>("http://localhost:9091");

// await api.ResetMappingsAsync().ConfigureAwait(false);
await api.ResetMappingsAsync().ConfigureAwait(false);

var mappingBuilder = api.GetMappingBuilder();
mappingBuilder.Given(m => m
Expand Down Expand Up @@ -51,13 +54,32 @@ static async Task Main(string[] args)
.WithPath("/bla3")
)
.WithResponse(rsp => rsp
.WithBodyAsJson(new
.WithBodyAsJson(new
{
x = "test"
}, true)
)
);

mappingBuilder.Given(m => m
.WithRequest(req => req
.WithPath("/test1")
.UsingPost()
.WithBody(b => b
.WithJmesPathMatcher("things.name == 'RequiredThing'")
)
)
.WithResponse(rsp => rsp
.WithHeaders(h => h.Add("Content-Type", "application/json"))
.WithDelay(TimeSpan.FromMilliseconds(50))
.WithStatusCode(200)
.WithBodyAsJson(new
{
status = "ok"
}, true)
)
);

var result = await mappingBuilder.BuildAndPostAsync().ConfigureAwait(false);
Console.WriteLine($"result = {JsonConvert.SerializeObject(result)}");

Expand Down Expand Up @@ -112,6 +134,9 @@ static async Task Main(string[] args)
var getFileResult = await api.GetFileAsync("1.cs");
Console.WriteLine($"getFileResult = {getFileResult}");

Console.WriteLine("Press any key to reset mappings");
Console.ReadKey();

var resetMappingsAsync = await api.ResetMappingsAsync();
Console.WriteLine($"resetMappingsAsync = {resetMappingsAsync.Status}");

Expand Down
8 changes: 0 additions & 8 deletions examples/WireMock.Net.Client/Properties/launchSettings.json

This file was deleted.

2 changes: 1 addition & 1 deletion examples/WireMock.Net.Client/WireMock.Net.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ApplicationIcon>../../resources/WireMock.Net-Logo.ico</ApplicationIcon>
</PropertyGroup>

Expand Down
130 changes: 130 additions & 0 deletions src/WireMock.Net.Abstractions/BuilderExtensions/BodyModelBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;

// ReSharper disable once CheckNamespace
namespace WireMock.Admin.Mappings;

/// <summary>
/// BodyModelBuilder
/// </summary>
public partial class BodyModelBuilder
{
public BodyModelBuilder WithNotNullOrEmptyMatcher(bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("NotNullOrEmptyMatcher")
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithCSharpCodeMatcher(string pattern, bool rejectOnMatch = false)
{
return WithMatcher("CSharpCodeMatcher", pattern, rejectOnMatch);
}

public BodyModelBuilder WithLinqMatcher(string pattern, bool rejectOnMatch = false)
{
return WithMatcher("LinqMatcher", pattern, rejectOnMatch);
}

public BodyModelBuilder WithExactMatcher(string pattern, bool rejectOnMatch = false)
{
return WithMatcher("ExactMatcher", pattern, rejectOnMatch);
}

public BodyModelBuilder WithExactObjectMatcher(object value, bool rejectOnMatch = false)
{
return WithMatcher("ExactObjectMatcher", value, rejectOnMatch);
}

public BodyModelBuilder WithGraphQLMatcher(string pattern, IDictionary<string, Type>? customScalars = null, bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("GraphQLMatcher")
.WithCustomScalars(customScalars)
.WithPattern(pattern)
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithProtoBufMatcher(string pattern, bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("ProtoBufMatcher")
.WithPattern(pattern)
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithRegexMatcher(string pattern, bool ignoreCase = false, bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("RegexMatcher")
.WithPattern(pattern)
.WithIgnoreCase(ignoreCase)
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithJsonMatcher(string pattern, bool ignoreCase = false, bool useRegex = false, bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("JsonMatcher")
.WithPattern(pattern)
.WithIgnoreCase(ignoreCase)
.WithRegex(useRegex)
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithJsonPartialMatcher(string pattern, bool ignoreCase = false, bool useRegex = false, bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("JsonPartialMatcher")
.WithPattern(pattern)
.WithIgnoreCase(ignoreCase)
.WithRegex(useRegex)
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithJsonPathMatcher(string pattern, bool rejectOnMatch = false)
{
return WithMatcher("JsonPathMatcher", pattern, rejectOnMatch);
}

public BodyModelBuilder WithJmesPathMatcher(string pattern, bool rejectOnMatch = false)
{
return WithMatcher("JmesPathMatcher", pattern, rejectOnMatch);
}

public BodyModelBuilder WithXPathMatcher(string pattern, XmlNamespace[]? xmlNamespaceMap = null, bool rejectOnMatch = false)
{
return WithMatcher(mb => mb
.WithName("PathMatcher")
.WithPattern(pattern)
.WithXmlNamespaceMap(xmlNamespaceMap)
.WithRejectOnMatch(rejectOnMatch)
);
}

public BodyModelBuilder WithWildcardMatcher(string pattern, bool ignoreCase = false, bool rejectOnMatch = false)
{
return WithMatcher("WildcardMatcher", pattern, rejectOnMatch, ignoreCase);
}

public BodyModelBuilder WithSimMetricsMatcher(string pattern, bool ignoreCase = false, bool rejectOnMatch = false)
{
return WithMatcher("SimMetricsMatcher", pattern, rejectOnMatch, ignoreCase);
}

private BodyModelBuilder WithMatcher(string name, object pattern, bool rejectOnMatch, bool ignoreCase = false)
{
return WithMatcher(mb => mb
.WithName(name)
.WithPattern(pattern)
.WithRejectOnMatch(rejectOnMatch)
.WithIgnoreCase(ignoreCase)
);
}
}
65 changes: 42 additions & 23 deletions src/WireMock.Net/Matchers/JsonMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public class JsonMatcher : IJsonMatcher
public bool Regex { get; }

private readonly JToken _valueAsJToken;
private readonly Func<JToken, JToken> _jTokenConverter;

/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
Expand Down Expand Up @@ -70,7 +69,6 @@ public JsonMatcher(MatchBehaviour matchBehaviour, object value, bool ignoreCase

Value = value;
_valueAsJToken = JsonUtils.ConvertValueToJToken(value);
_jTokenConverter = ignoreCase ? Rename : jToken => jToken;
}

/// <inheritdoc />
Expand All @@ -86,7 +84,7 @@ public MatchResult IsMatch(object? input)
{
var inputAsJToken = JsonUtils.ConvertValueToJToken(input);

var match = IsMatch(_jTokenConverter(_valueAsJToken), _jTokenConverter(inputAsJToken));
var match = IsMatch(RenameJToken(_valueAsJToken), RenameJToken(inputAsJToken));
score = MatchScores.ToScore(match);
}
catch (Exception ex)
Expand Down Expand Up @@ -179,38 +177,59 @@ protected virtual bool IsMatch(JToken value, JToken? input)
}
}

private static string? ToUpper(string? input)
// https://stackoverflow.com/questions/11679804/json-net-rename-properties
private JToken RenameJToken(JToken input)
{
return input?.ToUpperInvariant();
if (!IgnoreCase)
{
return input;
}

return input switch
{
JProperty property => RenameJProperty(property),
JArray array => RenameJArray(array),
JObject obj => RenameJObject(obj),
_ => input
};
}

// https://stackoverflow.com/questions/11679804/json-net-rename-properties
private static JToken Rename(JToken json)
private JProperty RenameJProperty(JProperty property)
{
if (json is JProperty property)
if (!IgnoreCase)
{
JToken propertyValue = property.Value;
if (propertyValue.Type == JTokenType.String)
{
string stringValue = propertyValue.Value<string>()!;
propertyValue = ToUpper(stringValue);
}

return new JProperty(ToUpper(property.Name)!, Rename(propertyValue));
return property;
}

if (json is JArray array)
var propertyValue = property.Value;
if (propertyValue.Type == JTokenType.String && !Regex)
{
var renamedValues = array.Select(Rename);
return new JArray(renamedValues);
var stringValue = propertyValue.Value<string>()!;
propertyValue = ToUpper(stringValue);
}

if (json is JObject obj)
return new JProperty(ToUpper(property.Name)!, RenameJToken(propertyValue));
}

private JArray RenameJArray(JArray array)
{
if (Regex)
{
var renamedProperties = obj.Properties().Select(Rename);
return new JObject(renamedProperties);
return array;
}

return json;
var renamedValues = array.Select(RenameJToken);
return new JArray(renamedValues);
}

private JObject RenameJObject(JObject obj)
{
var renamedProperties = obj.Properties().Select(RenameJProperty);
return new JObject(renamedProperties);
}

private static string? ToUpper(string? input)
{
return input?.ToUpperInvariant();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -385,4 +385,22 @@ public void JsonPartialWildcardMatcher_IsMatch_ValueAsJPathInvalidMatch(string v
// Assert
Assert.Equal(0.0, match);
}

[Fact]
public void JsonPartialWildcardMatcher_IsMatch_WithIgnoreCaseTrueAndRegexTrue_JObject()
{
// Assign
var matcher = new JsonPartialWildcardMatcher(new { id = 1, Number = "^\\d+$" }, ignoreCase: true, regex: true);

// Act
var jObject = new JObject
{
{ "Id", new JValue(1) },
{ "Number", new JValue(1) }
};
double match = matcher.IsMatch(jObject).Score;

// Assert
Assert.Equal(1.0, match);
}
}

0 comments on commit 3c44bce

Please sign in to comment.