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

Transform body as file #388

Merged
merged 2 commits into from
Dec 6, 2019
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
Original file line number Diff line number Diff line change
@@ -1 +1 @@
C# Hello
// C# Hello
5 changes: 5 additions & 0 deletions src/WireMock.Net/Admin/Mappings/ResponseModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class ResponseModel
/// </summary>
public bool? UseTransformer { get; set; }

/// <summary>
/// Use the Handlerbars transformer for the content from the referenced BodyAsFile.
/// </summary>
public bool? UseTransformerForBodyAsFile { get; set; }

/// <summary>
/// Gets or sets the headers.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public interface ITransformResponseBuilder : IDelayResponseBuilder
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
IResponseBuilder WithTransformer();
IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile = false);
}
}
12 changes: 9 additions & 3 deletions src/WireMock.Net/ResponseBuilders/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public partial class Response : IResponseBuilder
/// </summary>
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>
/// The Proxy URL to use.
/// </summary>
Expand Down Expand Up @@ -311,10 +316,11 @@ public IResponseBuilder WithBodyFromBase64(string bodyAsBase64, Encoding encodin
return this;
}

/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer"/>
public IResponseBuilder WithTransformer()
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile = false)
{
UseTransformer = true;
UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
return this;
}

Expand Down Expand Up @@ -414,7 +420,7 @@ public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMe
{
var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback);
var responseMessageTransformer = new ResponseMessageTransformer(factory);
return responseMessageTransformer.Transform(requestMessage, ResponseMessage);
return responseMessageTransformer.Transform(requestMessage, ResponseMessage, UseTransformerForBodyAsFile);
}

if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
Expand Down
5 changes: 5 additions & 0 deletions src/WireMock.Net/Serialization/MappingConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public MappingModel ToMappingModel(IMapping mapping)
mappingModel.Response.BodyAsFile = null;
mappingModel.Response.BodyAsFileIsCached = null;
mappingModel.Response.UseTransformer = null;
mappingModel.Response.UseTransformerForBodyAsFile = null;
mappingModel.Response.BodyEncoding = null;
mappingModel.Response.ProxyUrl = response.ProxyUrl;
mappingModel.Response.Fault = null;
Expand All @@ -125,6 +126,10 @@ public MappingModel ToMappingModel(IMapping mapping)
{
mappingModel.Response.UseTransformer = response.UseTransformer;
}
if (response.UseTransformerForBodyAsFile)
{
mappingModel.Response.UseTransformerForBodyAsFile = response.UseTransformerForBodyAsFile;
}

if (response.ResponseMessage.BodyData != null)
{
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net/Server/FluentMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ private IResponseBuilder InitResponseBuilder(ResponseModel responseModel)

if (responseModel.UseTransformer == true)
{
responseBuilder = responseBuilder.WithTransformer();
responseBuilder = responseBuilder.WithTransformer(responseModel.UseTransformerForBodyAsFile == true);
}

if (!string.IsNullOrEmpty(responseModel.ProxyUrl))
Expand Down
11 changes: 11 additions & 0 deletions src/WireMock.Net/Transformers/HandlebarsContext.cs
Original file line number Diff line number Diff line change
@@ -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; }
}
}
16 changes: 10 additions & 6 deletions src/WireMock.Net/Transformers/HandlebarsContextFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@ public HandlebarsContextFactory(IFileSystemHandler fileSystemHandler, Action<IHa
_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
};
}
}
}
}
12 changes: 12 additions & 0 deletions src/WireMock.Net/Transformers/IHandlebarsContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using HandlebarsDotNet;
using WireMock.Handlers;

namespace WireMock.Transformers
{
interface IHandlebarsContext
{
IHandlebars Handlebars { get; set; }

IFileSystemHandler FileSystemHandler { get; set; }
}
}
2 changes: 1 addition & 1 deletion src/WireMock.Net/Transformers/IHandlebarsContextFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ namespace WireMock.Transformers
{
interface IHandlebarsContextFactory
{
IHandlebars Create();
IHandlebarsContext Create();
}
}
54 changes: 35 additions & 19 deletions src/WireMock.Net/Transformers/ResponseMessageTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using HandlebarsDotNet;
using JetBrains.Annotations;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
Expand All @@ -21,7 +20,7 @@ public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
_factory = factory;
}

public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original)
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
{
var handlebarsContext = _factory.Create();

Expand All @@ -36,7 +35,7 @@ public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage
break;

case BodyType.File:
TransformBodyAsFile(handlebarsContext, template, original, responseMessage);
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
break;

case BodyType.String:
Expand All @@ -52,9 +51,9 @@ public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage
var newHeaders = new Dictionary<string, WireMockList<string>>();
foreach (var header in original.Headers)
{
var templateHeaderKey = handlebarsContext.Compile(header.Key);
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
var templateHeaderValues = header.Value
.Select(handlebarsContext.Compile)
.Select(handlebarsContext.Handlebars.Compile)
.Select(func => func(template))
.ToArray();

Expand All @@ -66,7 +65,7 @@ public ResponseMessage Transform(RequestMessage requestMessage, 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;
switch (original.BodyData.BodyAsJson)
Expand Down Expand Up @@ -94,7 +93,7 @@ private static void TransformBodyAsJson(IHandlebars handlebarsContext, object te
};
}

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)
{
Expand All @@ -121,7 +120,7 @@ private static void WalkNode(IHandlebars handlebarsContext, JToken node, object
return;
}

var templateForStringValue = handlebarsContext.Compile(stringValue);
var templateForStringValue = handlebarsContext.Handlebars.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
Expand Down Expand Up @@ -153,9 +152,9 @@ private static void ReplaceNodeValue(JToken node, string stringValue)
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
{
Expand All @@ -165,16 +164,33 @@ private static void TransformBodyAsString(IHandlebars handlebarsContext, object
};
}

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,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsFile = templateBodyAsFile(template)
};
responseMessage.BodyData = new BodyData
{
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
};
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Moq;
using Newtonsoft.Json;
using NFluent;
using WireMock.Handlers;
using WireMock.Models;
using WireMock.ResponseBuilders;
using WireMock.Settings;
Expand Down Expand Up @@ -226,7 +227,7 @@ public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()

var response = Response.Create()
.WithTransformer()
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\test.xml"); // why use a \\ here ?
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");

// Act
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
Expand All @@ -235,6 +236,30 @@ public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()
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]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath()
{
Expand Down