When using ResponseMessageTransformer : keep BodyEncoding (#460)

This commit is contained in:
Stef Heyenrath
2020-04-29 08:40:49 +02:00
committed by GitHub
parent bf5afef7a1
commit a6cf7a48dc
2 changed files with 666 additions and 637 deletions

View File

@@ -1,233 +1,236 @@
using HandlebarsDotNet; using HandlebarsDotNet;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using WireMock.Types; using System.Text;
using WireMock.Util; using WireMock.Types;
using WireMock.Validation; using WireMock.Util;
using WireMock.Validation;
namespace WireMock.Transformers
{ namespace WireMock.Transformers
internal class ResponseMessageTransformer {
{ internal class ResponseMessageTransformer
private readonly IHandlebarsContextFactory _factory; {
private readonly IHandlebarsContextFactory _factory;
public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
{ public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
Check.NotNull(factory, nameof(factory)); {
Check.NotNull(factory, nameof(factory));
_factory = factory;
} _factory = factory;
}
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
{ public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
var handlebarsContext = _factory.Create(); {
var handlebarsContext = _factory.Create();
var responseMessage = new ResponseMessage();
var responseMessage = new ResponseMessage();
var template = new { request = requestMessage };
var template = new { request = requestMessage };
switch (original.BodyData?.DetectedBodyType)
{ switch (original.BodyData?.DetectedBodyType)
case BodyType.Json: {
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage); case BodyType.Json:
break; TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);
break;
case BodyType.File:
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile); case BodyType.File:
break; TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
break;
case BodyType.String:
responseMessage.BodyOriginal = original.BodyData.BodyAsString; case BodyType.String:
TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage); responseMessage.BodyOriginal = original.BodyData.BodyAsString;
break; TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage);
} break;
}
responseMessage.FaultType = original.FaultType;
responseMessage.FaultPercentage = original.FaultPercentage; responseMessage.FaultType = original.FaultType;
responseMessage.FaultPercentage = original.FaultPercentage;
// Headers
var newHeaders = new Dictionary<string, WireMockList<string>>(); // Headers
foreach (var header in original.Headers) var newHeaders = new Dictionary<string, WireMockList<string>>();
{ foreach (var header in original.Headers)
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key); {
var templateHeaderValues = header.Value var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
.Select(handlebarsContext.Handlebars.Compile) var templateHeaderValues = header.Value
.Select(func => func(template)) .Select(handlebarsContext.Handlebars.Compile)
.ToArray(); .Select(func => func(template))
.ToArray();
newHeaders.Add(templateHeaderKey(template), new WireMockList<string>(templateHeaderValues));
} newHeaders.Add(templateHeaderKey(template), new WireMockList<string>(templateHeaderValues));
}
responseMessage.Headers = newHeaders;
responseMessage.Headers = newHeaders;
switch (original.StatusCode)
{ switch (original.StatusCode)
case int statusCodeAsInteger: {
responseMessage.StatusCode = statusCodeAsInteger; case int statusCodeAsInteger:
break; responseMessage.StatusCode = statusCodeAsInteger;
break;
case string statusCodeAsString:
var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString); case string statusCodeAsString:
responseMessage.StatusCode = templateForStatusCode(template); var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString);
break; responseMessage.StatusCode = templateForStatusCode(template);
} break;
}
return responseMessage;
} return responseMessage;
}
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{ private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
JToken jToken; {
switch (original.BodyData.BodyAsJson) JToken jToken;
{ switch (original.BodyData.BodyAsJson)
case JObject bodyAsJObject: {
jToken = bodyAsJObject.DeepClone(); case JObject bodyAsJObject:
WalkNode(handlebarsContext, jToken, template); jToken = bodyAsJObject.DeepClone();
break; WalkNode(handlebarsContext, jToken, template);
break;
case Array bodyAsArray:
jToken = JArray.FromObject(bodyAsArray); case Array bodyAsArray:
WalkNode(handlebarsContext, jToken, template); jToken = JArray.FromObject(bodyAsArray);
break; WalkNode(handlebarsContext, jToken, template);
break;
case string bodyAsString:
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template); case string bodyAsString:
break; jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template);
break;
default:
jToken = JObject.FromObject(original.BodyData.BodyAsJson); default:
WalkNode(handlebarsContext, jToken, template); jToken = JObject.FromObject(original.BodyData.BodyAsJson);
break; WalkNode(handlebarsContext, jToken, template);
} break;
}
responseMessage.BodyData = new BodyData
{ responseMessage.BodyData = new BodyData
DetectedBodyType = original.BodyData.DetectedBodyType, {
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType, Encoding = original.BodyData.Encoding,
BodyAsJson = jToken DetectedBodyType = original.BodyData.DetectedBodyType,
}; DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
} BodyAsJson = jToken
};
private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context) }
{
var templateForStringValue = handlebarsContext.Compile(stringValue); private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context)
string transformedString = templateForStringValue(context); {
if (!string.Equals(stringValue, transformedString)) var templateForStringValue = handlebarsContext.Compile(stringValue);
{ string transformedString = templateForStringValue(context);
const string property = "_"; if (!string.Equals(stringValue, transformedString))
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}"); {
JToken node = dummy[property]; const string property = "_";
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
ReplaceNodeValue(node, transformedString); JToken node = dummy[property];
return dummy[property]; ReplaceNodeValue(node, transformedString);
}
return dummy[property];
return stringValue; }
}
return stringValue;
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context) }
{
if (node.Type == JTokenType.Object) private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
{ {
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions. if (node.Type == JTokenType.Object)
foreach (JProperty child in node.Children<JProperty>().ToArray()) {
{ // In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
WalkNode(handlebarsContext, child.Value, context); foreach (JProperty child in node.Children<JProperty>().ToArray())
} {
} WalkNode(handlebarsContext, child.Value, context);
else if (node.Type == JTokenType.Array) }
{ }
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions. else if (node.Type == JTokenType.Array)
foreach (JToken child in node.Children().ToArray()) {
{ // In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
WalkNode(handlebarsContext, child, context); foreach (JToken child in node.Children().ToArray())
} {
} WalkNode(handlebarsContext, child, context);
else if (node.Type == JTokenType.String) }
{ }
// In case of string, try to transform the value. else if (node.Type == JTokenType.String)
string stringValue = node.Value<string>(); {
if (string.IsNullOrEmpty(stringValue)) // In case of string, try to transform the value.
{ string stringValue = node.Value<string>();
return; if (string.IsNullOrEmpty(stringValue))
} {
return;
var templateForStringValue = handlebarsContext.Compile(stringValue); }
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString)) var templateForStringValue = handlebarsContext.Compile(stringValue);
{ string transformedString = templateForStringValue(context);
ReplaceNodeValue(node, transformedString); if (!string.Equals(stringValue, transformedString))
} {
} ReplaceNodeValue(node, transformedString);
} }
}
private static void ReplaceNodeValue(JToken node, string stringValue) }
{
if (bool.TryParse(stringValue, out bool valueAsBoolean)) private static void ReplaceNodeValue(JToken node, string stringValue)
{ {
node.Replace(valueAsBoolean); if (bool.TryParse(stringValue, out bool valueAsBoolean))
return; {
} node.Replace(valueAsBoolean);
return;
JToken value; }
try
{ JToken value;
// Try to convert this string into a JsonObject try
value = JToken.Parse(stringValue); {
} // Try to convert this string into a JsonObject
catch (JsonException) value = JToken.Parse(stringValue);
{ }
// Ignore JsonException and just keep string value and convert to JToken catch (JsonException)
value = stringValue; {
} // Ignore JsonException and just keep string value and convert to JToken
value = stringValue;
node.Replace(value); }
}
node.Replace(value);
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage) }
{
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString); private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
responseMessage.BodyData = new BodyData var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);
{
DetectedBodyType = original.BodyData.DetectedBodyType, responseMessage.BodyData = new BodyData
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType, {
BodyAsString = templateBodyAsString(template) Encoding = original.BodyData.Encoding,
}; DetectedBodyType = original.BodyData.DetectedBodyType,
} DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
BodyAsString = templateBodyAsString(template)
private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile) };
{ }
var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
string transformedBodyAsFilename = templateBodyAsFile(template); private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
{
if (!useTransformerForBodyAsFile) 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, responseMessage.BodyData = new BodyData
BodyAsFile = transformedBodyAsFilename {
}; DetectedBodyType = original.BodyData.DetectedBodyType,
} DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
else BodyAsFile = transformedBodyAsFilename
{ };
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename); }
var templateBodyAsString = handlebarsContext.Handlebars.Compile(text); else
{
responseMessage.BodyData = new BodyData string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
{ var templateBodyAsString = handlebarsContext.Handlebars.Compile(text);
DetectedBodyType = BodyType.String,
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType, responseMessage.BodyData = new BodyData
BodyAsString = templateBodyAsString(template), {
BodyAsFile = transformedBodyAsFilename DetectedBodyType = BodyType.String,
}; DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
} BodyAsString = templateBodyAsString(template),
} BodyAsFile = transformedBodyAsFilename
} };
}
}
}
} }

View File

@@ -1,406 +1,432 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using Moq; using Moq;
using Newtonsoft.Json; using Newtonsoft.Json;
using NFluent; using NFluent;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Models; using WireMock.Models;
using WireMock.ResponseBuilders; using WireMock.ResponseBuilders;
using WireMock.Settings; using WireMock.Settings;
using WireMock.Types; using WireMock.Types;
using WireMock.Util; using WireMock.Util;
using Xunit; using Xunit;
#if NET452 #if NET452
using Microsoft.Owin; using Microsoft.Owin;
#else #else
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
#endif #endif
namespace WireMock.Net.Tests.ResponseBuilders namespace WireMock.Net.Tests.ResponseBuilders
{ {
public class ResponseWithHandlebarsTests public class ResponseWithHandlebarsTests
{ {
private readonly WireMockServerSettings _settings = new WireMockServerSettings(); private readonly WireMockServerSettings _settings = new WireMockServerSettings();
private const string ClientIp = "::1"; private const string ClientIp = "::1";
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithNullBody_ShouldNotThrowException() public async Task Response_ProvideResponse_Handlebars_WithNullBody_ShouldNotThrowException()
{ {
// Assign // Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock")); var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, "GET", ClientIp); var request = new RequestMessage(urlDetails, "GET", ClientIp);
var response = Response.Create() var response = Response.Create()
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
responseMessage.BodyData.Should().BeNull(); responseMessage.BodyData.Should().BeNull();
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb() public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "whatever", BodyAsString = "whatever",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
var response = Response.Create() var response = Response.Create()
.WithBody("test {{request.url}} {{request.path}} {{request.method}}") .WithBody("test {{request.url}} {{request.path}} {{request.method}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
} }
[Theory] [Theory]
[InlineData("Get")] [InlineData("Get")]
[InlineData("Post")] [InlineData("Post")]
public async Task Response_ProvideResponse_Handlebars_UrlPath(string httpMethod) public async Task Response_ProvideResponse_Handlebars_UrlPath(string httpMethod)
{ {
// Assign // Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock")); var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, httpMethod, ClientIp); var request = new RequestMessage(urlDetails, httpMethod, ClientIp);
var response = Response.Create() var response = Response.Create()
.WithBody("{{request.url}} {{request.absoluteurl}} {{request.path}} {{request.absolutepath}}") .WithBody("{{request.url}} {{request.absoluteurl}} {{request.path}} {{request.absolutepath}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("http://localhost/a/b http://localhost/wiremock/a/b /a/b /wiremock/a/b"); Check.That(responseMessage.BodyData.BodyAsString).Equals("http://localhost/a/b http://localhost/wiremock/a/b /a/b /wiremock/a/b");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_PathSegments() public async Task Response_ProvideResponse_Handlebars_PathSegments()
{ {
// Assign // Assign
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock")); var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
var request = new RequestMessage(urlDetails, "POST", ClientIp); var request = new RequestMessage(urlDetails, "POST", ClientIp);
var response = Response.Create() var response = Response.Create()
.WithBody("{{request.pathsegments.[0]}} {{request.absolutepathsegments.[0]}}") .WithBody("{{request.pathsegments.[0]}} {{request.absolutepathsegments.[0]}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock"); Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_Query() public async Task Response_ProvideResponse_Handlebars_Query()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "abc", BodyAsString = "abc",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body); var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
var response = Response.Create() var response = Response.Create()
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}") .WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_StatusCode() public async Task Response_ProvideResponse_Handlebars_StatusCode()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "abc", BodyAsString = "abc",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body); var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
var response = Response.Create() var response = Response.Create()
.WithStatusCode("{{request.query.a}}") .WithStatusCode("{{request.query.a}}")
.WithBody("test") .WithBody("test")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.StatusCode).Equals("400"); Check.That(responseMessage.StatusCode).Equals("400");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_StatusCodeIsNull() public async Task Response_ProvideResponse_Handlebars_StatusCodeIsNull()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "abc", BodyAsString = "abc",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body); var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
var response = Response.Create() var response = Response.Create()
.WithBody("test") .WithBody("test")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.StatusCode).Equals(null); Check.That(responseMessage.StatusCode).Equals(null);
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_Header() public async Task Response_ProvideResponse_Handlebars_Header()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "abc", BodyAsString = "abc",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } }); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer(); var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.Headers).ContainsKey("x"); Check.That(responseMessage.Headers).ContainsKey("x");
Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain"); Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_Headers() public async Task Response_ProvideResponse_Handlebars_Headers()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "abc", BodyAsString = "abc",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } }); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer(); var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
Check.That(responseMessage.Headers).ContainsKey("x"); Check.That(responseMessage.Headers).ContainsKey("x");
Check.That(responseMessage.Headers["x"]).Contains("text/plain"); Check.That(responseMessage.Headers["x"]).Contains("text/plain");
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo"); Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host() public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
{ {
// Assign // Assign
var body = new BodyData var body = new BodyData
{ {
BodyAsString = "abc", BodyAsString = "abc",
DetectedBodyType = BodyType.String DetectedBodyType = BodyType.String
}; };
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body); var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
var response = Response.Create() var response = Response.Create()
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}") .WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost"); Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsObject() public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsObject()
{ {
// Assign // Assign
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }"; string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData var bodyData = new BodyData
{ {
BodyAsJson = JsonConvert.DeserializeObject(jsonString), BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json, DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8 Encoding = Encoding.UTF8
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData); var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create() var response = Response.Create()
.WithBodyAsJson(new { x = "test {{request.path}}" }) .WithBodyAsJson(new { x = "test {{request.path}}" })
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}"); Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray() public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray()
{ {
// Assign // Assign
string jsonString = "{ \"a\": \"test 1\", \"b\": \"test 2\" }"; string jsonString = "{ \"a\": \"test 1\", \"b\": \"test 2\" }";
var bodyData = new BodyData var bodyData = new BodyData
{ {
BodyAsJson = JsonConvert.DeserializeObject(jsonString), BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json, DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8 Encoding = Encoding.UTF8
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData); var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData);
var response = Response.Create() var response = Response.Create()
.WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" }) .WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" })
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]"); Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile() public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()
{ {
// Assign // Assign
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 response = Response.Create() var response = Response.Create()
.WithTransformer() .WithTransformer()
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml"); .WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml"); Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_And_TransformContentFromBodyAsFile() public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_And_TransformContentFromBodyAsFile()
{ {
// 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 response = Response.Create() var response = Response.Create()
.WithTransformer(true) .WithTransformer(true)
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml"); .WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml"); Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String); Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String);
Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>"); Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath() public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath()
{ {
// Assign // Assign
string jsonString = "{ \"MyUniqueNumber\": \"1\" }"; string jsonString = "{ \"MyUniqueNumber\": \"1\" }";
var bodyData = new BodyData var bodyData = new BodyData
{ {
BodyAsString = jsonString, BodyAsString = jsonString,
BodyAsJson = JsonConvert.DeserializeObject(jsonString), BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json, DetectedBodyType = BodyType.Json,
DetectedBodyTypeFromContentType = BodyType.Json, DetectedBodyTypeFromContentType = BodyType.Json,
Encoding = Encoding.UTF8 Encoding = Encoding.UTF8
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData); var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
string jsonPath = "\"$.MyUniqueNumber\""; string jsonPath = "\"$.MyUniqueNumber\"";
var response = Response.Create() var response = Response.Create()
.WithTransformer() .WithTransformer()
.WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ? .WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ?
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json"); Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsNormalString() public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsNormalString()
{ {
// Assign // Assign
string jsonString = "{ \"name\": \"WireMock\" }"; string jsonString = "{ \"name\": \"WireMock\" }";
var bodyData = new BodyData var bodyData = new BodyData
{ {
BodyAsJson = JsonConvert.DeserializeObject(jsonString), BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json, DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8 Encoding = Encoding.UTF8
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData); var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create() var response = Response.Create()
.WithBodyAsJson("test") .WithBodyAsJson("test")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\""); Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\"");
} }
[Fact] [Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsHandlebarsString() public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsHandlebarsString()
{ {
// Assign // Assign
string jsonString = "{ \"name\": \"WireMock\" }"; string jsonString = "{ \"name\": \"WireMock\" }";
var bodyData = new BodyData var bodyData = new BodyData
{ {
BodyAsJson = JsonConvert.DeserializeObject(jsonString), BodyAsJson = JsonConvert.DeserializeObject(jsonString),
DetectedBodyType = BodyType.Json, DetectedBodyType = BodyType.Json,
Encoding = Encoding.UTF8 Encoding = Encoding.UTF8
}; };
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData); var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create() var response = Response.Create()
.WithBodyAsJson("{{{request.bodyAsJson}}}") .WithBodyAsJson("{{{request.bodyAsJson}}}")
.WithTransformer(); .WithTransformer();
// Act // Act
var responseMessage = await response.ProvideResponseAsync(request, _settings); var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert // Assert
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}"); Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
} }
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsString_KeepsEncoding()
{
// Assign
const string text = "my-text";
Encoding enc = Encoding.Unicode;
var bodyData = new BodyData
{
BodyAsString = text,
DetectedBodyType = BodyType.String,
Encoding = enc
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBody("{{request.body}}", BodyDestinationFormat.SameAsSource, enc)
.WithTransformer();
// Act
var responseMessage = await response.ProvideResponseAsync(request, _settings);
// Assert
responseMessage.BodyData.BodyAsString.Should().Be(text);
responseMessage.BodyData.Encoding.Should().Be(enc);
}
}
} }