diff --git a/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs b/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
index 4d558889..14956902 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
@@ -13,6 +13,8 @@ namespace WireMock.ResponseBuilders;
public partial class Response
{
+ private bool _bodyFromFileSet;
+
///
public IResponseBuilder WithBody(Func bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
{
@@ -78,6 +80,8 @@ public partial class Response
{
Guard.NotNull(filename);
+ _bodyFromFileSet = true;
+
ResponseMessage.BodyData = new BodyData
{
BodyAsFileIsCached = cache,
diff --git a/src/WireMock.Net/ResponseBuilders/Response.WithTransformer.cs b/src/WireMock.Net/ResponseBuilders/Response.WithTransformer.cs
new file mode 100644
index 00000000..0b2fc062
--- /dev/null
+++ b/src/WireMock.Net/ResponseBuilders/Response.WithTransformer.cs
@@ -0,0 +1,36 @@
+// Copyright © WireMock.Net
+
+using System;
+using WireMock.Types;
+
+namespace WireMock.ResponseBuilders;
+
+public partial class Response
+{
+ ///
+ public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
+ {
+ return WithTransformer(TransformerType.Handlebars, transformContentFromBodyAsFile);
+ }
+
+ ///
+ public IResponseBuilder WithTransformer(ReplaceNodeOptions options)
+ {
+ return WithTransformer(TransformerType.Handlebars, false, options);
+ }
+
+ ///
+ public IResponseBuilder WithTransformer(TransformerType transformerType, bool transformContentFromBodyAsFile = false, ReplaceNodeOptions options = ReplaceNodeOptions.EvaluateAndTryToConvert)
+ {
+ if (_bodyFromFileSet)
+ {
+ throw new InvalidOperationException("WithTransformer should be used before WithBodyFromFile.");
+ }
+
+ UseTransformer = true;
+ TransformerType = transformerType;
+ UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
+ TransformerReplaceNodeOptions = options;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs
index e9e7537f..017f38e9 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.cs
@@ -164,28 +164,6 @@ public partial class Response : IResponseBuilder
return WithStatusCode((int)HttpStatusCode.NotFound);
}
- ///
- public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
- {
- return WithTransformer(TransformerType.Handlebars, transformContentFromBodyAsFile);
- }
-
- ///
- public IResponseBuilder WithTransformer(ReplaceNodeOptions options)
- {
- return WithTransformer(TransformerType.Handlebars, false, options);
- }
-
- ///
- public IResponseBuilder WithTransformer(TransformerType transformerType, bool transformContentFromBodyAsFile = false, ReplaceNodeOptions options = ReplaceNodeOptions.EvaluateAndTryToConvert)
- {
- UseTransformer = true;
- TransformerType = transformerType;
- UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
- TransformerReplaceNodeOptions = options;
- return this;
- }
-
///
public IResponseBuilder WithDelay(TimeSpan delay)
{
@@ -286,7 +264,7 @@ public partial class Response : IResponseBuilder
if (UseTransformer)
{
- // Check if the body matcher is a RequestMessageProtoBufMatcher and try to to decode the byte-array to a BodyAsJson.
+ // Check if the body matcher is a RequestMessageProtoBufMatcher and try to decode the byte-array to a BodyAsJson.
if (mapping.RequestMatcher is Request requestMatcher && requestMessage is RequestMessage request)
{
var protoBufMatcher = requestMatcher.GetRequestMessageMatcher()?.Matcher;
diff --git a/src/WireMock.Net/Transformers/Transformer.cs b/src/WireMock.Net/Transformers/Transformer.cs
index 0e87813c..fb993f53 100644
--- a/src/WireMock.Net/Transformers/Transformer.cs
+++ b/src/WireMock.Net/Transformers/Transformer.cs
@@ -198,7 +198,7 @@ internal class Transformer : ITransformer
private JToken ReplaceSingleNode(ITransformerContext transformerContext, ReplaceNodeOptions options, string stringValue, object model)
{
- string transformedString = transformerContext.ParseAndRender(stringValue, model);
+ var transformedString = transformerContext.ParseAndRender(stringValue, model);
if (!string.Equals(stringValue, transformedString))
{
@@ -346,7 +346,7 @@ internal class Transformer : ITransformer
private static IBodyData TransformBodyAsFile(ITransformerContext transformerContext, object model, IBodyData original, bool useTransformerForBodyAsFile)
{
- string transformedBodyAsFilename = transformerContext.ParseAndRender(original.BodyAsFile!, model);
+ var transformedBodyAsFilename = transformerContext.ParseAndRender(original.BodyAsFile!, model);
if (!useTransformerForBodyAsFile)
{
@@ -358,7 +358,7 @@ internal class Transformer : ITransformer
};
}
- string text = transformerContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
+ var text = transformerContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
return new BodyData
{
DetectedBodyType = BodyType.String,
diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs
index ae205fe8..278d4615 100644
--- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs
+++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithTransformerTests.cs
@@ -602,22 +602,21 @@ public class ResponseWithTransformerTests
Check.That(response.Message.BodyData!.BodyAsFile).Equals(@"c:\1\test.xml");
}
- [Theory]
- [InlineData(TransformerType.Handlebars)]
- //[InlineData(TransformerType.Scriban)] ["c:\\["1"]\\test.xml"]
- //[InlineData(TransformerType.ScribanDotLiquid)]
- public async Task Response_ProvideResponse_Transformer_WithBodyAsFile_And_TransformContentFromBodyAsFile(TransformerType transformerType)
+ [Fact]
+ public async Task Response_ProvideResponse_Transformer_WithBodyAsFile_And_TransformContentFromBodyAsFile()
{
// Assign
var filesystemHandlerMock = new Mock(MockBehavior.Strict);
- filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny())).Returns("");
+ filesystemHandlerMock
+ .Setup(fs => fs.ReadResponseBodyAsString(It.IsAny()))
+ .Returns("");
_settings.FileSystemHandler = filesystemHandlerMock.Object;
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
var responseBuilder = Response.Create()
- .WithTransformer(transformerType, true)
+ .WithTransformer(transformContentFromBodyAsFile: true)
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act
diff --git a/test/WireMock.Net.Tests/WireMockServerTests.WithTransformer.cs b/test/WireMock.Net.Tests/WireMockServerTests.WithTransformer.cs
new file mode 100644
index 00000000..22e94056
--- /dev/null
+++ b/test/WireMock.Net.Tests/WireMockServerTests.WithTransformer.cs
@@ -0,0 +1,98 @@
+// Copyright © WireMock.Net
+
+using System;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+using FluentAssertions;
+using WireMock.RequestBuilders;
+using WireMock.ResponseBuilders;
+using WireMock.Server;
+using Xunit;
+
+namespace WireMock.Net.Tests;
+
+public partial class WireMockServerTests
+{
+ private const string RequestXml =
+ """
+
+
+
+ """;
+
+ private readonly string _responseFilePath = Path.Combine(Environment.CurrentDirectory, "__admin", "mappings", "responseWithTransformer.xml");
+
+ [Fact]
+ public async Task WireMockServer_WithTransformer_WithBody_ShouldWork()
+ {
+ // Arrange
+ using var server = WireMockServer.Start();
+ server
+ .WhenRequest(req => req
+ .WithPath("/withbody")
+ .UsingPost())
+ .ThenRespondWith(rsp => rsp
+ .WithSuccess()
+ .WithBody(File.ReadAllText(_responseFilePath))
+ .WithTransformer());
+
+ // Act
+ var response = await GetResponseAsync(server, "/withbody");
+
+ // Assert
+ response.Should().Contain("Hello, Stef!");
+ }
+
+ [Fact]
+ public async Task WireMockServer_WithTransformerBefore_WithBodyFromFile_ShouldWork()
+ {
+ // Arrange
+ using var server = WireMockServer.Start();
+ server
+ .WhenRequest(req => req
+ .WithPath("/withbodyfromfile")
+ .UsingPost())
+ .ThenRespondWith(rsp => rsp
+ .WithSuccess()
+ .WithTransformer(transformContentFromBodyAsFile: true)
+ .WithBodyFromFile(_responseFilePath));
+
+ // Act
+ var response = await GetResponseAsync(server, "/withbodyfromfile");
+
+ // Assert
+ response.Should().Contain("Hello, Stef!");
+ }
+
+ [Fact]
+ public void WireMockServer_WithTransformerAfter_WithBodyFromFile_ShouldThrow()
+ {
+ // Act
+ var act = () =>
+ {
+ using var server = WireMockServer.Start();
+ server
+ .WhenRequest(req => req
+ .WithPath("/")
+ .UsingPost())
+ .ThenRespondWith(rsp => rsp
+ .WithSuccess()
+ .WithBodyFromFile(_responseFilePath)
+ .WithTransformer(transformContentFromBodyAsFile: true));
+ };
+
+ // Assert
+ act.Should().Throw().WithMessage("WithTransformer should be used before WithBodyFromFile.");
+ }
+
+ private static async Task GetResponseAsync(WireMockServer server, string relativePath)
+ {
+ using HttpClient httpClient = new HttpClient();
+ httpClient.BaseAddress = new Uri(server.Urls[0]);
+
+ using var requestContent = new StringContent(RequestXml);
+ using var responseMsg = await httpClient.PostAsync(relativePath, requestContent);
+ return await responseMsg.Content.ReadAsStringAsync();
+ }
+}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/__admin/mappings/responseWithTransformer.xml b/test/WireMock.Net.Tests/__admin/mappings/responseWithTransformer.xml
new file mode 100644
index 00000000..f7b3846b
--- /dev/null
+++ b/test/WireMock.Net.Tests/__admin/mappings/responseWithTransformer.xml
@@ -0,0 +1,3 @@
+
+ Hello, {{XPath.Evaluate request.body "//*[local-name()='Contact']/@FirstName"}}!
+