mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01: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
|
||||
{
|
||||
private bool _bodyFromFileSet;
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
|
||||
_bodyFromFileSet = true;
|
||||
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/// <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 />
|
||||
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<RequestMessageProtoBufMatcher>()?.Matcher;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<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;
|
||||
|
||||
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
|
||||
|
||||
@@ -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