mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-14 06:17:11 +01:00
Support json path in the response (#170)
* jsonpath in response * Fix tests * Support also BodyAsJson * Fix Sonar Issue * Add example (zubinix2) * Fix batch file * Solve CodeFactor issues * netcoreapp2.0;netcoreapp2.1 * 1.0.4.8
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||
<Version>1.0.4.7</Version>
|
||||
<Version>1.0.4.8-preview-01</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@@ -73,10 +73,21 @@ namespace WireMock.Matchers
|
||||
JToken jtokenInput = input is JToken tokenInput ? tokenInput : JObject.FromObject(input);
|
||||
|
||||
// Check if JToken or string or object
|
||||
JToken jtokenValue =
|
||||
Value is JToken tokenValue ? tokenValue :
|
||||
Value is string stringValue ? JToken.Parse(stringValue) :
|
||||
JObject.FromObject(input);
|
||||
JToken jtokenValue;
|
||||
switch (Value)
|
||||
{
|
||||
case JToken tokenValue:
|
||||
jtokenValue = tokenValue;
|
||||
break;
|
||||
|
||||
case string stringValue:
|
||||
jtokenValue = JToken.Parse(stringValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
jtokenValue = JObject.FromObject(Value);
|
||||
break;
|
||||
}
|
||||
|
||||
match = JToken.DeepEquals(jtokenValue, jtokenInput);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
namespace WireMock.Matchers
|
||||
namespace WireMock.Matchers
|
||||
{
|
||||
internal static class MatchBehaviourHelper
|
||||
{
|
||||
|
||||
@@ -76,6 +76,11 @@ namespace WireMock.Owin
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (responseMessage == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
response.StatusCode = responseMessage.StatusCode;
|
||||
|
||||
byte[] bytes = null;
|
||||
|
||||
@@ -701,7 +701,6 @@ namespace WireMock.Server
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseModel.BodyEncoding));
|
||||
}
|
||||
|
||||
else if (responseModel.BodyAsFile != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBodyFromFile(responseModel.BodyAsFile);
|
||||
|
||||
@@ -14,6 +14,7 @@ using WireMock.Owin;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Transformers;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Server
|
||||
@@ -387,7 +388,6 @@ namespace WireMock.Server
|
||||
public void SetMaxRequestLogCount([CanBeNull] int? maxRequestLogCount)
|
||||
{
|
||||
_options.MaxRequestLogCount = maxRequestLogCount;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
89
src/WireMock.Net/Transformers/HandleBarsHelpers.cs
Normal file
89
src/WireMock.Net/Transformers/HandleBarsHelpers.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HandlebarsDotNet;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandlebarsHelpers
|
||||
{
|
||||
public static void Register()
|
||||
{
|
||||
Handlebars.RegisterHelper("JsonPath.SelectToken", (writer, context, arguments) =>
|
||||
{
|
||||
(JObject valueToProcess, string jsonpath) = Parse(arguments);
|
||||
|
||||
JToken result = null;
|
||||
try
|
||||
{
|
||||
result = valueToProcess.SelectToken(jsonpath);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and return
|
||||
return;
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
writer.WriteSafeString(result);
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("JsonPath.SelectTokens", (writer, options, context, arguments) =>
|
||||
{
|
||||
(JObject valueToProcess, string jsonpath) = Parse(arguments);
|
||||
|
||||
IEnumerable<JToken> values = null;
|
||||
try
|
||||
{
|
||||
values = valueToProcess.SelectTokens(jsonpath);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and return
|
||||
return;
|
||||
}
|
||||
|
||||
if (values == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
foreach (JToken value in values)
|
||||
{
|
||||
options.Template(writer, new { id, value });
|
||||
id++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static (JObject valueToProcess, string jsonpath) Parse(object[] arguments)
|
||||
{
|
||||
Check.Condition(arguments, args => args.Length == 2, nameof(arguments));
|
||||
Check.NotNull(arguments[0], "arguments[0]");
|
||||
Check.NotNullOrEmpty(arguments[1] as string, "arguments[1]");
|
||||
|
||||
JObject valueToProcess;
|
||||
|
||||
switch (arguments[0])
|
||||
{
|
||||
case string jsonAsString:
|
||||
valueToProcess = JObject.Parse(jsonAsString);
|
||||
break;
|
||||
|
||||
case JObject jsonAsJObject:
|
||||
valueToProcess = jsonAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"The value '{arguments[0]}' with type {arguments[0].GetType()} cannot be used in Handlebars JsonPath.");
|
||||
}
|
||||
|
||||
return (valueToProcess, arguments[1] as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,18 @@
|
||||
using System.Linq;
|
||||
using HandlebarsDotNet;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class ResponseMessageTransformer
|
||||
{
|
||||
static ResponseMessageTransformer()
|
||||
{
|
||||
HandlebarsHelpers.Register();
|
||||
}
|
||||
|
||||
public static ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original)
|
||||
{
|
||||
bool bodyIsJson = original.BodyAsJson != null;
|
||||
@@ -20,21 +26,13 @@ namespace WireMock.Transformers
|
||||
|
||||
var template = new { request = requestMessage };
|
||||
|
||||
// Body
|
||||
Formatting formatting = original.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
||||
string body = bodyIsJson ? JsonConvert.SerializeObject(original.BodyAsJson, formatting) : original.Body;
|
||||
if (body != null)
|
||||
if (!bodyIsJson)
|
||||
{
|
||||
var templateBody = Handlebars.Compile(body);
|
||||
|
||||
if (!bodyIsJson)
|
||||
{
|
||||
responseMessage.Body = templateBody(template);
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage.BodyAsJson = JsonConvert.DeserializeObject(templateBody(template));
|
||||
}
|
||||
TransformBodyAsString(template, original, responseMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
TransformBodyAsJson(template, original, responseMessage);
|
||||
}
|
||||
|
||||
// Headers
|
||||
@@ -54,5 +52,79 @@ namespace WireMock.Transformers
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private static void TransformBodyAsJson(object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
JObject jobject;
|
||||
switch (original.BodyAsJson)
|
||||
{
|
||||
case JObject bodyAsJObject:
|
||||
jobject = bodyAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
jobject = JObject.FromObject(original.BodyAsJson);
|
||||
break;
|
||||
}
|
||||
|
||||
WalkNode(jobject, template);
|
||||
|
||||
responseMessage.BodyAsJson = jobject;
|
||||
}
|
||||
|
||||
private static void WalkNode(JToken node, object template)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
// In case of Object, loop all children.
|
||||
foreach (JProperty child in node.Children<JProperty>())
|
||||
{
|
||||
WalkNode(child.Value, template);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
// In case of Array, loop all items.
|
||||
foreach (JToken child in node.Children())
|
||||
{
|
||||
WalkNode(child, template);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.String)
|
||||
{
|
||||
// In case of string, try to transform the value.
|
||||
string stringValue = node.Value<string>();
|
||||
if (string.IsNullOrEmpty(stringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var templateForStringValue = Handlebars.Compile(stringValue);
|
||||
string transformedString = templateForStringValue(template);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
JToken value;
|
||||
try
|
||||
{
|
||||
// Try to convert this string into a real JsonObject
|
||||
value = JToken.Parse(transformedString);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and just convert to JToken
|
||||
value = transformedString;
|
||||
}
|
||||
|
||||
node.Replace(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void TransformBodyAsString(object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
var templateBody = Handlebars.Compile(original.Body);
|
||||
|
||||
responseMessage.Body = templateBody(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
|
||||
<AssemblyTitle>WireMock.Net</AssemblyTitle>
|
||||
<Version>1.0.4.7</Version>
|
||||
<Version>1.0.4.8-preview-01</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
@@ -41,7 +41,7 @@
|
||||
<PackageReference Include="JetBrains.Annotations" Version="11.1.0">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.0" />
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
@@ -53,6 +53,7 @@
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
@@ -62,6 +63,7 @@
|
||||
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.0.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
@@ -69,6 +71,7 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="1.1.3" />
|
||||
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
|
||||
Reference in New Issue
Block a user