mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-18 15:10:17 +02:00
Throw exception in case WithTransformer is used after WithBodyFromFile (#1185)
* Fix .WithBodyFromFile + .WithTransformer combination * Ex
This commit is contained in:
@@ -13,6 +13,8 @@ namespace WireMock.ResponseBuilders;
|
|||||||
|
|
||||||
public partial class Response
|
public partial class Response
|
||||||
{
|
{
|
||||||
|
private bool _bodyFromFileSet;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
|
||||||
{
|
{
|
||||||
@@ -78,6 +80,8 @@ public partial class Response
|
|||||||
{
|
{
|
||||||
Guard.NotNull(filename);
|
Guard.NotNull(filename);
|
||||||
|
|
||||||
|
_bodyFromFileSet = true;
|
||||||
|
|
||||||
ResponseMessage.BodyData = new BodyData
|
ResponseMessage.BodyData = new BodyData
|
||||||
{
|
{
|
||||||
BodyAsFileIsCached = cache,
|
BodyAsFileIsCached = cache,
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using WireMock.Types;
|
||||||
|
|
||||||
|
namespace WireMock.ResponseBuilders;
|
||||||
|
|
||||||
|
public partial class Response
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
|
||||||
|
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
|
||||||
|
{
|
||||||
|
return WithTransformer(TransformerType.Handlebars, transformContentFromBodyAsFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(ReplaceNodeOptions)"/>
|
||||||
|
public IResponseBuilder WithTransformer(ReplaceNodeOptions options)
|
||||||
|
{
|
||||||
|
return WithTransformer(TransformerType.Handlebars, false, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -164,28 +164,6 @@ public partial class Response : IResponseBuilder
|
|||||||
return WithStatusCode((int)HttpStatusCode.NotFound);
|
return WithStatusCode((int)HttpStatusCode.NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(bool)"/>
|
|
||||||
public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile)
|
|
||||||
{
|
|
||||||
return WithTransformer(TransformerType.Handlebars, transformContentFromBodyAsFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ITransformResponseBuilder.WithTransformer(ReplaceNodeOptions)"/>
|
|
||||||
public IResponseBuilder WithTransformer(ReplaceNodeOptions options)
|
|
||||||
{
|
|
||||||
return WithTransformer(TransformerType.Handlebars, false, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IResponseBuilder WithTransformer(TransformerType transformerType, bool transformContentFromBodyAsFile = false, ReplaceNodeOptions options = ReplaceNodeOptions.EvaluateAndTryToConvert)
|
|
||||||
{
|
|
||||||
UseTransformer = true;
|
|
||||||
TransformerType = transformerType;
|
|
||||||
UseTransformerForBodyAsFile = transformContentFromBodyAsFile;
|
|
||||||
TransformerReplaceNodeOptions = options;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IResponseBuilder WithDelay(TimeSpan delay)
|
public IResponseBuilder WithDelay(TimeSpan delay)
|
||||||
{
|
{
|
||||||
@@ -286,7 +264,7 @@ public partial class Response : IResponseBuilder
|
|||||||
|
|
||||||
if (UseTransformer)
|
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)
|
if (mapping.RequestMatcher is Request requestMatcher && requestMessage is RequestMessage request)
|
||||||
{
|
{
|
||||||
var protoBufMatcher = requestMatcher.GetRequestMessageMatcher<RequestMessageProtoBufMatcher>()?.Matcher;
|
var protoBufMatcher = requestMatcher.GetRequestMessageMatcher<RequestMessageProtoBufMatcher>()?.Matcher;
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ internal class Transformer : ITransformer
|
|||||||
|
|
||||||
private JToken ReplaceSingleNode(ITransformerContext transformerContext, ReplaceNodeOptions options, string stringValue, object model)
|
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))
|
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)
|
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)
|
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
|
return new BodyData
|
||||||
{
|
{
|
||||||
DetectedBodyType = BodyType.String,
|
DetectedBodyType = BodyType.String,
|
||||||
|
|||||||
@@ -602,22 +602,21 @@ public class ResponseWithTransformerTests
|
|||||||
Check.That(response.Message.BodyData!.BodyAsFile).Equals(@"c:\1\test.xml");
|
Check.That(response.Message.BodyData!.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Fact]
|
||||||
[InlineData(TransformerType.Handlebars)]
|
public async Task Response_ProvideResponse_Transformer_WithBodyAsFile_And_TransformContentFromBodyAsFile()
|
||||||
//[InlineData(TransformerType.Scriban)] ["c:\\["1"]\\test.xml"]
|
|
||||||
//[InlineData(TransformerType.ScribanDotLiquid)]
|
|
||||||
public async Task Response_ProvideResponse_Transformer_WithBodyAsFile_And_TransformContentFromBodyAsFile(TransformerType transformerType)
|
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("<xml MyUniqueNumber=\"{{request.query.MyUniqueNumber}}\"></xml>");
|
filesystemHandlerMock
|
||||||
|
.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>()))
|
||||||
|
.Returns("<xml MyUniqueNumber=\"{{request.query.MyUniqueNumber}}\"></xml>");
|
||||||
|
|
||||||
_settings.FileSystemHandler = filesystemHandlerMock.Object;
|
_settings.FileSystemHandler = filesystemHandlerMock.Object;
|
||||||
|
|
||||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||||
|
|
||||||
var responseBuilder = Response.Create()
|
var responseBuilder = Response.Create()
|
||||||
.WithTransformer(transformerType, true)
|
.WithTransformer(transformContentFromBodyAsFile: true)
|
||||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|||||||
@@ -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 =
|
||||||
|
"""
|
||||||
|
<xml>
|
||||||
|
<Contact FirstName = "Stef" />
|
||||||
|
</xml>
|
||||||
|
""";
|
||||||
|
|
||||||
|
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<InvalidOperationException>().WithMessage("WithTransformer should be used before WithBodyFromFile.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<string> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<xml>
|
||||||
|
<hello>Hello, {{XPath.Evaluate request.body "//*[local-name()='Contact']/@FirstName"}}!</hello>
|
||||||
|
</xml>
|
||||||
Reference in New Issue
Block a user