diff --git a/Directory.Build.props b/Directory.Build.props index 36db2bfb..085afa88 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ - 1.0.14 + 1.0.15 diff --git a/README.md b/README.md index 82988722..bfa2eae5 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w * Record/playback of stubs (proxying) * Per-request conditional proxying * Stateful behaviour simulation -* Response transformation +* Response templating / transformation using Handlebars and extensions ## Info | | | diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs index 3df50690..82ba0852 100644 --- a/src/WireMock.Net/ResponseBuilders/Response.cs +++ b/src/WireMock.Net/ResponseBuilders/Response.cs @@ -224,7 +224,7 @@ namespace WireMock.ResponseBuilders BodyAsFileIsCached = cache }; - if (cache) + if (cache && !UseTransformer) { ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; ResponseMessage.BodyData.BodyAsBytes = _fileSystemHandler.ReadResponseBodyAsFile(filename); diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs index 3ba9ebff..1da20c3c 100644 --- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs +++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs @@ -722,6 +722,11 @@ namespace WireMock.Server responseBuilder = responseBuilder.WithDelay(responseModel.Delay.Value); } + if (responseModel.UseTransformer) + { + responseBuilder = responseBuilder.WithTransformer(); + } + if (!string.IsNullOrEmpty(responseModel.ProxyUrl)) { if (string.IsNullOrEmpty(responseModel.X509Certificate2ThumbprintOrSubjectName)) @@ -778,11 +783,6 @@ namespace WireMock.Server responseBuilder = responseBuilder.WithBodyFromFile(responseModel.BodyAsFile); } - if (responseModel.UseTransformer) - { - responseBuilder = responseBuilder.WithTransformer(); - } - return responseBuilder; } diff --git a/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs b/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs index cdd8ae82..e2c742dc 100644 --- a/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs +++ b/src/WireMock.Net/Transformers/ResponseMessageTransformer.cs @@ -1,9 +1,9 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using HandlebarsDotNet; +using HandlebarsDotNet; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Linq; using WireMock.Util; namespace WireMock.Transformers @@ -24,23 +24,24 @@ namespace WireMock.Transformers public static ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original) { - bool bodyIsJson = original.BodyData.DetectedBodyType == BodyType.Json; var responseMessage = new ResponseMessage { StatusCode = original.StatusCode }; - if (!bodyIsJson) - { - responseMessage.BodyOriginal = original.BodyData.BodyAsString; - } - var template = new { request = requestMessage }; - if (!bodyIsJson) + switch (original.BodyData.DetectedBodyType) { - TransformBodyAsString(template, original, responseMessage); - } - else - { - TransformBodyAsJson(template, original, responseMessage); + case BodyType.Json: + TransformBodyAsJson(template, original, responseMessage); + break; + + case BodyType.File: + TransformBodyAsFile(template, original, responseMessage); + break; + + case BodyType.String: + responseMessage.BodyOriginal = original.BodyData.BodyAsString; + TransformBodyAsString(template, original, responseMessage); + break; } // Headers @@ -150,13 +151,25 @@ namespace WireMock.Transformers private static void TransformBodyAsString(object template, ResponseMessage original, ResponseMessage responseMessage) { - var templateBody = HandlebarsContext.Compile(original.BodyData.BodyAsString); + var templateBodyAsString = HandlebarsContext.Compile(original.BodyData.BodyAsString); responseMessage.BodyData = new BodyData { DetectedBodyType = original.BodyData.DetectedBodyType, DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType, - BodyAsString = templateBody(template) + BodyAsString = templateBodyAsString(template) + }; + } + + private static void TransformBodyAsFile(object template, ResponseMessage original, ResponseMessage responseMessage) + { + var templateBodyAsFile = HandlebarsContext.Compile(original.BodyData.BodyAsFile); + + responseMessage.BodyData = new BodyData + { + DetectedBodyType = original.BodyData.DetectedBodyType, + DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType, + BodyAsFile = templateBodyAsFile(template) }; } } diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithHandlebarsTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithHandlebarsTests.cs index d609be14..31011f5b 100644 --- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithHandlebarsTests.cs +++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithHandlebarsTests.cs @@ -214,5 +214,22 @@ namespace WireMock.Net.Tests.ResponseBuilders // Assert Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]"); } + + [Fact] + public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile() + { + // Assign + var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp); + + var response = Response.Create() + .WithTransformer() + .WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\test.xml"); // why use a \\ here ? + + // Act + var responseMessage = await response.ProvideResponseAsync(request); + + // Assert + Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml"); + } } } \ No newline at end of file