Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for string and object in JsonMatcher. #157

Merged
merged 2 commits into from
Jun 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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