Transform body as file (#388)

* .

* fix
This commit is contained in:
Stef Heyenrath
2019-12-06 06:52:08 +01:00
committed by GitHub
parent a47750c058
commit 8bafd6a1ba
12 changed files with 117 additions and 33 deletions

View File

@@ -1 +1 @@
C# Hello // C# Hello

View File

@@ -62,6 +62,11 @@ namespace WireMock.Admin.Mappings
/// </summary> /// </summary>
public bool? UseTransformer { get; set; } public bool? UseTransformer { get; set; }
/// <summary>
/// Use the Handlerbars transformer for the content from the referenced BodyAsFile.
/// </summary>
public bool? UseTransformerForBodyAsFile { get; set; }
/// <summary> /// <summary>
/// Gets or sets the headers. /// Gets or sets the headers.
/// </summary> /// </summary>

View File

@@ -11,6 +11,6 @@
/// <returns> /// <returns>
/// The <see cref="IResponseBuilder"/>. /// The <see cref="IResponseBuilder"/>.
/// </returns> /// </returns>
IResponseBuilder WithTransformer(); IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile = false);
} }
} }

View File

@@ -33,6 +33,11 @@ namespace WireMock.ResponseBuilders
/// </summary> /// </summary>
public bool UseTransformer { get; private set; } public bool UseTransformer { get; private set; }
/// <summary>
/// Gets a value indicating whether to use the Handlerbars transformer for the content from the referenced BodyAsFile.
/// </summary>
public bool UseTransformerForBodyAsFile { get; private set; }
/// <summary> /// <summary>
/// The Proxy URL to use. /// The Proxy URL to use.
/// </summary> /// </summary>
@@ -311,10 +316,11 @@ namespace WireMock.ResponseBuilders
return this; return this;
} }
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer"/> /// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
public IResponseBuilder WithTransformer() public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile = false)
{ {
UseTransformer = true; UseTransformer = true;
UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
return this; return this;
} }
@@ -414,7 +420,7 @@ namespace WireMock.ResponseBuilders
{ {
var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback); var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback);
var responseMessageTransformer = new ResponseMessageTransformer(factory); var responseMessageTransformer = new ResponseMessageTransformer(factory);
return responseMessageTransformer.Transform(requestMessage, ResponseMessage); return responseMessageTransformer.Transform(requestMessage, ResponseMessage, UseTransformerForBodyAsFile);
} }
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true) if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)

View File

@@ -112,6 +112,7 @@ namespace WireMock.Serialization
mappingModel.Response.BodyAsFile = null; mappingModel.Response.BodyAsFile = null;
mappingModel.Response.BodyAsFileIsCached = null; mappingModel.Response.BodyAsFileIsCached = null;
mappingModel.Response.UseTransformer = null; mappingModel.Response.UseTransformer = null;
mappingModel.Response.UseTransformerForBodyAsFile = null;
mappingModel.Response.BodyEncoding = null; mappingModel.Response.BodyEncoding = null;
mappingModel.Response.ProxyUrl = response.ProxyUrl; mappingModel.Response.ProxyUrl = response.ProxyUrl;
mappingModel.Response.Fault = null; mappingModel.Response.Fault = null;
@@ -125,6 +126,10 @@ namespace WireMock.Serialization
{ {
mappingModel.Response.UseTransformer = response.UseTransformer; mappingModel.Response.UseTransformer = response.UseTransformer;
} }
if (response.UseTransformerForBodyAsFile)
{
mappingModel.Response.UseTransformerForBodyAsFile = response.UseTransformerForBodyAsFile;
}
if (response.ResponseMessage.BodyData != null) if (response.ResponseMessage.BodyData != null)
{ {

View File

@@ -785,7 +785,7 @@ namespace WireMock.Server
if (responseModel.UseTransformer == true) if (responseModel.UseTransformer == true)
{ {
responseBuilder = responseBuilder.WithTransformer(); responseBuilder = responseBuilder.WithTransformer(responseModel.UseTransformerForBodyAsFile == true);
} }
if (!string.IsNullOrEmpty(responseModel.ProxyUrl)) if (!string.IsNullOrEmpty(responseModel.ProxyUrl))

View File

@@ -0,0 +1,11 @@
using HandlebarsDotNet;
using WireMock.Handlers;
namespace WireMock.Transformers
{
internal class HandlebarsContext : IHandlebarsContext
{
public IHandlebars Handlebars { get; set; }
public IFileSystemHandler FileSystemHandler { get; set; }
}
}

View File

@@ -20,15 +20,19 @@ namespace WireMock.Transformers
_action = action; _action = action;
} }
public IHandlebars Create() public IHandlebarsContext Create()
{ {
var handlebarsContext = Handlebars.Create(HandlebarsConfiguration); var handlebars = Handlebars.Create(HandlebarsConfiguration);
HandlebarsHelpers.Register(handlebarsContext, _fileSystemHandler); HandlebarsHelpers.Register(handlebars, _fileSystemHandler);
_action?.Invoke(handlebarsContext, _fileSystemHandler); _action?.Invoke(handlebars, _fileSystemHandler);
return handlebarsContext; return new HandlebarsContext
{
Handlebars = handlebars,
FileSystemHandler = _fileSystemHandler
};
} }
} }
} }

View File

@@ -0,0 +1,12 @@
using HandlebarsDotNet;
using WireMock.Handlers;
namespace WireMock.Transformers
{
interface IHandlebarsContext
{
IHandlebars Handlebars { get; set; }
IFileSystemHandler FileSystemHandler { get; set; }
}
}

View File

@@ -4,6 +4,6 @@ namespace WireMock.Transformers
{ {
interface IHandlebarsContextFactory interface IHandlebarsContextFactory
{ {
IHandlebars Create(); IHandlebarsContext Create();
} }
} }

View File

@@ -1,5 +1,4 @@
using HandlebarsDotNet; using JetBrains.Annotations;
using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System; using System;
@@ -21,7 +20,7 @@ namespace WireMock.Transformers
_factory = factory; _factory = factory;
} }
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original) public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
{ {
var handlebarsContext = _factory.Create(); var handlebarsContext = _factory.Create();
@@ -36,7 +35,7 @@ namespace WireMock.Transformers
break; break;
case BodyType.File: case BodyType.File:
TransformBodyAsFile(handlebarsContext, template, original, responseMessage); TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
break; break;
case BodyType.String: case BodyType.String:
@@ -52,9 +51,9 @@ namespace WireMock.Transformers
var newHeaders = new Dictionary<string, WireMockList<string>>(); var newHeaders = new Dictionary<string, WireMockList<string>>();
foreach (var header in original.Headers) foreach (var header in original.Headers)
{ {
var templateHeaderKey = handlebarsContext.Compile(header.Key); var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
var templateHeaderValues = header.Value var templateHeaderValues = header.Value
.Select(handlebarsContext.Compile) .Select(handlebarsContext.Handlebars.Compile)
.Select(func => func(template)) .Select(func => func(template))
.ToArray(); .ToArray();
@@ -66,7 +65,7 @@ namespace WireMock.Transformers
return responseMessage; return responseMessage;
} }
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage) private static void TransformBodyAsJson(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{ {
JToken jToken; JToken jToken;
switch (original.BodyData.BodyAsJson) switch (original.BodyData.BodyAsJson)
@@ -94,7 +93,7 @@ namespace WireMock.Transformers
}; };
} }
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context) private static void WalkNode(IHandlebarsContext handlebarsContext, JToken node, object context)
{ {
if (node.Type == JTokenType.Object) if (node.Type == JTokenType.Object)
{ {
@@ -121,7 +120,7 @@ namespace WireMock.Transformers
return; return;
} }
var templateForStringValue = handlebarsContext.Compile(stringValue); var templateForStringValue = handlebarsContext.Handlebars.Compile(stringValue);
string transformedString = templateForStringValue(context); string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString)) if (!string.Equals(stringValue, transformedString))
{ {
@@ -153,9 +152,9 @@ namespace WireMock.Transformers
node.Replace(value); node.Replace(value);
} }
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage) private static void TransformBodyAsString(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{ {
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString); var templateBodyAsString = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsString);
responseMessage.BodyData = new BodyData responseMessage.BodyData = new BodyData
{ {
@@ -165,16 +164,33 @@ namespace WireMock.Transformers
}; };
} }
private static void TransformBodyAsFile(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage) private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
{ {
var templateBodyAsFile = handlebarsContext.Compile(original.BodyData.BodyAsFile); var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
string transformedBodyAsFilename = templateBodyAsFile(template);
responseMessage.BodyData = new BodyData if (!useTransformerForBodyAsFile)
{ {
DetectedBodyType = original.BodyData.DetectedBodyType, responseMessage.BodyData = new BodyData
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType, {
BodyAsFile = templateBodyAsFile(template) DetectedBodyType = original.BodyData.DetectedBodyType,
}; DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsFile = transformedBodyAsFilename
};
}
else
{
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
var templateBodyAsString = handlebarsContext.Handlebars.Compile(text);
responseMessage.BodyData = new BodyData
{
DetectedBodyType = BodyType.String,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsString = templateBodyAsString(template),
BodyAsFile = transformedBodyAsFilename
};
}
} }
} }
} }

View File

@@ -5,6 +5,7 @@ using System.Threading.Tasks;
using Moq; using Moq;
using Newtonsoft.Json; using Newtonsoft.Json;
using NFluent; using NFluent;
using WireMock.Handlers;
using WireMock.Models; using WireMock.Models;
using WireMock.ResponseBuilders; using WireMock.ResponseBuilders;
using WireMock.Settings; using WireMock.Settings;
@@ -226,7 +227,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
var response = Response.Create() var response = Response.Create()
.WithTransformer() .WithTransformer()
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\test.xml"); // why use a \\ here ? .WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object); var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
@@ -235,6 +236,30 @@ namespace WireMock.Net.Tests.ResponseBuilders
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml"); Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
} }
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_And_TransformContentFromBodyAsFile()
{
// Assign
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("<xml MyUniqueNumber=\"{{request.query.MyUniqueNumber}}\"></xml>");
_settingsMock.SetupGet(s => s.FileSystemHandler).Returns(filesystemHandlerMock.Object);
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
var response = Response.Create()
.WithTransformer(true)
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
// Assert
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String);
Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
}
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath() public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath()
{ {