Skip to content

Commit

Permalink
Support for string and object in JsonMatcher. (#157)
Browse files Browse the repository at this point in the history
* JsonMatcher (#154)

* small update in example code
  • Loading branch information
StefH authored Jun 26, 2018
1 parent b269001 commit 4283732
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 42 deletions.
20 changes: 14 additions & 6 deletions examples/WireMock.Net.ConsoleApplication/MainApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,22 @@ public static void Run()
server
.Given(Request
.Create()
.WithPath("/jsonbodytest")
.WithPath("/jsonbodytest1")
.WithBody(new JsonMatcher("{ \"x\": 42, \"s\": \"s\" }"))
.UsingPost())
.WithGuid("debaf408-3b23-4c04-9d18-ef1c020e79f2")
.RespondWith(Response.Create()
.WithBody(@"{ ""result"": ""jsonbodytest"" }"));
.WithBody(@"{ ""result"": ""jsonbodytest1"" }"));

server
.Given(Request
.Create()
.WithPath("/jsonbodytest2")
.WithBody(new JsonMatcher(new { x = 42, s = "s" }))
.UsingPost())
.WithGuid("debaf408-3b23-4c04-9d18-ef1c020e79f3")
.RespondWith(Response.Create()
.WithBody(@"{ ""result"": ""jsonbodytest2"" }"));

server
.Given(Request
Expand All @@ -77,7 +87,6 @@ public static void Run()
.Given(Request.Create().WithPath("/headers", "/headers_test").UsingPost().WithHeader("Content-Type", "application/json*"))
.RespondWith(Response.Create()
.WithStatusCode(201)
//.WithHeader("MyHeader", "application/json", "application/json2")
.WithHeader("Content-Type", "application/json")
.WithBodyAsJson(new { result = "data:headers posted with 201" }));

Expand Down Expand Up @@ -184,8 +193,6 @@ public static void Run()
.WithStatusCode(HttpStatusCode.Unauthorized)
.WithBody(@"{ ""result"": ""api-key missing""}"));



server
.Given(Request.Create().WithPath("/nobody").UsingGet())
.RespondWith(Response.Create().WithDelay(TimeSpan.FromSeconds(1))
Expand All @@ -195,14 +202,15 @@ public static void Run()
.Given(Request.Create().WithPath("/partial").UsingPost().WithBody(new SimMetricsMatcher(new[] { "cat", "dog" })))
.RespondWith(Response.Create().WithStatusCode(200).WithBody("partial = 200"));

// http://localhost:8080/any/any?start=1000&stop=1&stop=2
// http://localhost:8080/trans?start=1000&stop=1&stop=2
server
.Given(Request.Create().WithPath("/trans").UsingGet())
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json")
.WithHeader("Transformed-Postman-Token", "token is {{request.headers.Postman-Token}}")
.WithHeader("xyz_{{request.headers.Postman-Token}}", "token is {{request.headers.Postman-Token}}")
.WithBody(@"{""msg"": ""Hello world CATCH-ALL on /*, {{request.path}}, bykey={{request.query.start}}, bykey={{request.query.stop}}, byidx0={{request.query.stop.[0]}}, byidx1={{request.query.stop.[1]}}"" }")
.WithTransformer()
.WithDelay(TimeSpan.FromMilliseconds(100))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,18 @@
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
Expand All @@ -53,6 +63,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
11 changes: 11 additions & 0 deletions examples/WireMock.Net.StandAlone.Net452/app.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
3 changes: 3 additions & 0 deletions examples/WireMock.Net.StandAlone.Net452/packages.config
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.8" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.4" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
</packages>
13 changes: 4 additions & 9 deletions src/WireMock.Net/Admin/Mappings/MatcherModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,14 @@ public class MatcherModel
public string Name { get; set; }

/// <summary>
/// Gets or sets the value. Used by <see cref="Matchers.JsonMatcher"/>.
/// Gets or sets the pattern. Can be a string (default) or an object;
/// </summary>
public string Value { get; set; }
public object Pattern { get; set; }

/// <summary>
/// Gets or sets the pattern.
/// Gets or sets the patterns. Can be array of strings (default) or an array of objects;
/// </summary>
public string Pattern { get; set; }

/// <summary>
/// Gets or sets the patterns.
/// </summary>
public string[] Patterns { get; set; }
public object[] Patterns { get; set; }

/// <summary>
/// Gets or sets the ignore case.
Expand Down
4 changes: 2 additions & 2 deletions src/WireMock.Net/Matchers/IValueMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
public interface IValueMatcher: IObjectMatcher
{
/// <summary>
/// Gets the value.
/// Gets the value (can be a string or an obejct).
/// </summary>
/// <returns>Value</returns>
string GetValue();
object Value { get; }
}
}
43 changes: 34 additions & 9 deletions src/WireMock.Net/Matchers/JsonMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace WireMock.Matchers
/// </summary>
public class JsonMatcher : IValueMatcher
{
private readonly string _value;
/// <inheritdoc cref="IValueMatcher.Value"/>
public object Value { get; }

/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "JsonMatcher";
Expand All @@ -21,22 +22,43 @@ public class JsonMatcher : IValueMatcher
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="value">The value to check for equality.</param>
/// <param name="value">The string value to check for equality.</param>
public JsonMatcher([NotNull] string value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="value">The object value to check for equality.</param>
public JsonMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value to check for equality.</param>
/// <param name="value">The string value to check for equality.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value)
{
Check.NotNull(value, nameof(value));

MatchBehaviour = matchBehaviour;
_value = value;
Value = value;
}

/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The object value to check for equality.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
{
Check.NotNull(value, nameof(value));

MatchBehaviour = matchBehaviour;
Value = value;
}

/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
Expand All @@ -48,9 +70,15 @@ public double IsMatch(object input)
try
{
// Check if JToken or object
JToken jtoken = input is JToken token ? token : JObject.FromObject(input);
JToken jtokenInput = input is JToken tokenInput ? tokenInput : JObject.FromObject(input);

match = JToken.DeepEquals(JToken.Parse(_value), jtoken);
// Check if JToken or string or object
JToken jtokenValue =
Value is JToken tokenValue ? tokenValue :
Value is string stringValue ? JToken.Parse(stringValue) :
JObject.FromObject(input);

match = JToken.DeepEquals(jtokenValue, jtokenInput);
}
catch (JsonException)
{
Expand All @@ -60,8 +88,5 @@ public double IsMatch(object input)

return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
}

/// <inheritdoc cref="IValueMatcher.GetValue"/>
public string GetValue() => _value;
}
}
24 changes: 14 additions & 10 deletions src/WireMock.Net/Serialization/MatcherMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,28 @@ public static IMatcher Map([CanBeNull] MatcherModel matcher)
string matcherName = parts[0];
string matcherType = parts.Length > 1 ? parts[1] : null;

string[] patterns = matcher.Patterns ?? new[] { matcher.Pattern };
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new [] { matcher.Pattern as string };
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;

switch (matcherName)
{
case "ExactMatcher":
return new ExactMatcher(matchBehaviour, patterns);
return new ExactMatcher(matchBehaviour, stringPatterns);

case "RegexMatcher":
return new RegexMatcher(matchBehaviour, patterns, matcher.IgnoreCase == true);
return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);

case "JsonMatcher":
return new JsonMatcher(matchBehaviour, matcher.Pattern);

case "JsonPathMatcher":
return new JsonPathMatcher(matchBehaviour, patterns);
return new JsonPathMatcher(matchBehaviour, stringPatterns);

case "XPathMatcher":
return new XPathMatcher(matchBehaviour, matcher.Pattern);
return new XPathMatcher(matchBehaviour, (string) matcher.Pattern);

case "WildcardMatcher":
return new WildcardMatcher(matchBehaviour, patterns, matcher.IgnoreCase == true);
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);

case "SimMetricsMatcher":
SimMetricType type = SimMetricType.Levenstein;
Expand All @@ -51,7 +51,7 @@ public static IMatcher Map([CanBeNull] MatcherModel matcher)
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
}

return new SimMetricsMatcher(matchBehaviour, matcher.Pattern, type);
return new SimMetricsMatcher(matchBehaviour, (string) matcher.Pattern, type);

default:
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
Expand All @@ -70,9 +70,13 @@ public static MatcherModel Map([CanBeNull] IMatcher matcher)
return null;
}

string[] patterns = matcher is IStringMatcher stringMatcher ?
stringMatcher.GetPatterns() :
matcher is IValueMatcher valueMatcher ? new[] { valueMatcher.GetValue() } : new string[0];
// If the matcher is a IStringMatcher, get the patterns.
// If the matcher is a IValueMatcher, get the value (can be string or object).
// Else empty array
object[] patterns = matcher is IStringMatcher stringMatcher ?
stringMatcher.GetPatterns().Cast<object>().ToArray() :
matcher is IValueMatcher valueMatcher ? new[] { valueMatcher.Value } :
new object[0];
bool? ignorecase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : (bool?)null;
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : (bool?)null;

Expand Down
6 changes: 5 additions & 1 deletion src/WireMock.Net/Server/FluentMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,11 @@ private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage respons
}
});

if (requestMessage.Body != null)
if (requestMessage.BodyAsJson != null)
{
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));
}
else if (requestMessage.Body != null)
{
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
}
Expand Down
2 changes: 1 addition & 1 deletion test/WireMock.Net.Tests/FluentMockServerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void FluentMockServer_ReadStaticMapping_WithResponseBodyFromFile()
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
string json = File.ReadAllText(folder);

string responseBodyFilePath = Path.Combine(GetCurrentFolder(), "ResponseBodyFiles", "responsebody.json");
string responseBodyFilePath = Path.Combine(GetCurrentFolder(), "responsebody.json");

dynamic jsonObj = JsonConvert.DeserializeObject(json);
jsonObj["Response"]["BodyAsFile"] = responseBodyFilePath;
Expand Down
38 changes: 35 additions & 3 deletions test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void JsonMatcher_GetValue()
var matcher = new JsonMatcher("{}");

// Act
string value = matcher.GetValue();
object value = matcher.Value;

// Assert
Check.That(value).Equals("{}");
Expand Down Expand Up @@ -62,7 +62,39 @@ public void JsonMatcher_IsMatch_NullObject()
}

[Fact]
public void JsonMatcher_IsMatch_JObject()
public void JsonMatcher_IsMatch_JObject1()
{
// Assign
var matcher = new JsonMatcher(new { Id = 1, Name = "test" });

// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);

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

[Fact]
public void JsonMatcher_IsMatch_JObject2()
{
// Assign
var matcher = new JsonMatcher(new { Id = 1, Name = "test" });

// Act
var jobject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
double match = matcher.IsMatch(jobject);

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

[Fact]
public void JsonMatcher_IsMatch_JObjectAsString()
{
// Assign
var matcher = new JsonMatcher("{ \"Id\" : 1, \"Name\" : \"Test\" }");
Expand All @@ -80,7 +112,7 @@ public void JsonMatcher_IsMatch_JObject()
}

[Fact]
public void JsonMatcher_IsMatch_JObject_RejectOnMatch()
public void JsonMatcher_IsMatch_JObjectAsString_RejectOnMatch()
{
// Assign
var matcher = new JsonMatcher(MatchBehaviour.RejectOnMatch, "{ \"Id\" : 1, \"Name\" : \"Test\" }");
Expand Down
2 changes: 1 addition & 1 deletion test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</ItemGroup>

<ItemGroup>
<None Update="ResponseBodyFiles\responsebody.json">
<None Update="responsebody.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\00000002-ee28-4f29-ae63-1ac9b0802d86.json">
Expand Down
File renamed without changes.

0 comments on commit 4283732

Please sign in to comment.