mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-18 07:00:04 +02:00
Update Handlebars Transformer logic (ReplaceNodeOptions) (#1036)
* Update Handlebars Transformer logic (ReplaceNodeOptions) * okeee * EvaluateAndKeep = Evaluate * fix? * linux * _ * tt * xxx * fx * x * fix test
This commit is contained in:
@@ -7,6 +7,7 @@ using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders;
|
||||
@@ -28,8 +29,10 @@ public class ResponseWithHandlebarsDateTimeTests
|
||||
_settings.FileSystemHandler = filesystemHandlerMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_WithBodyAsJson_ProvideResponseAsync_Handlebars_DateTime()
|
||||
[Theory]
|
||||
[InlineData(ReplaceNodeOptions.EvaluateAndTryToConvert, JTokenType.Integer)]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate, JTokenType.String)]
|
||||
public async Task Response_WithBodyAsJson_ProvideResponseAsync_Handlebars_DateTimeYear(ReplaceNodeOptions options, JTokenType expected)
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
@@ -39,14 +42,61 @@ public class ResponseWithHandlebarsDateTimeTests
|
||||
{
|
||||
DateTimeYear = "{{ DateTime.UtcNow \"yyyy\" }}"
|
||||
})
|
||||
.WithTransformer();
|
||||
.WithTransformer(options);
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
var j = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
j["DateTimeYear"]!.Value<string>().Should().Be(DateTime.Now.Year.ToString());
|
||||
var jObject = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
jObject["DateTimeYear"]!.Type.Should().Be(expected);
|
||||
jObject["DateTimeYear"]!.Value<string>().Should().Be(DateTime.Now.Year.ToString());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ReplaceNodeOptions.EvaluateAndTryToConvert, JTokenType.Date)]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate, JTokenType.String)]
|
||||
public async Task Response_WithBodyAsJson_ProvideResponseAsync_Handlebars_DateTime(ReplaceNodeOptions options, JTokenType expected)
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
DateTime = "{{ DateTime.UtcNow }}"
|
||||
})
|
||||
.WithTransformer(options);
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
var jObject = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
jObject["DateTime"]!.Type.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ReplaceNodeOptions.EvaluateAndTryToConvert, JTokenType.Integer)]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate, JTokenType.String)]
|
||||
public async Task Response_WithBodyAsJson_ProvideResponseAsync_Handlebars_DateTimeWithStringFormat(ReplaceNodeOptions options, JTokenType expected)
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
StringFormatDateTime = "{{ String.Format (DateTime.UtcNow) \"yyMMddhhmmss\" }}"
|
||||
})
|
||||
.WithTransformer(options);
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
var jObject = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
jObject["StringFormatDateTime"]!.Type.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -65,4 +115,39 @@ public class ResponseWithHandlebarsDateTimeTests
|
||||
// Assert
|
||||
response.Message.BodyData!.BodyAsString.Should().Contain($"DateTimeYear = \"{DateTime.Now.Year}\"");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ReplaceNodeOptions.EvaluateAndTryToConvert)]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate)]
|
||||
public async Task Response_WithBodyAsJson_ProvideResponseAsync_Handlebars_WithStringFormatAsString(ReplaceNodeOptions options)
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
FormatAsString1 = "{{ String.FormatAsString (DateTime.UtcNow) \"yyMMddhhmmss\" }}",
|
||||
FormatAsString2 = "{{ String.FormatAsString (DateTime.UtcNow) }}",
|
||||
FormatAsString3 = "{{ String.FormatAsString 42 \"X\" }}",
|
||||
FormatAsString4 = "{{ String.FormatAsString 42 }}"
|
||||
})
|
||||
.WithTransformer(options);
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
var jObject = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
jObject["FormatAsString1"]!.Type.Should().Be(JTokenType.String);
|
||||
jObject["FormatAsString2"]!.Type.Should().Be(JTokenType.String);
|
||||
|
||||
var formatAsString3 = jObject["FormatAsString3"]!;
|
||||
formatAsString3.Type.Should().Be(JTokenType.String);
|
||||
formatAsString3.Value<string>().Should().Be("2A");
|
||||
|
||||
var formatAsString4 = jObject["FormatAsString4"]!;
|
||||
formatAsString4.Type.Should().Be(JTokenType.String);
|
||||
formatAsString4.Value<string>().Should().Be("42");
|
||||
}
|
||||
}
|
||||
@@ -78,10 +78,8 @@ public class ResponseWithHandlebarsRandomTests
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate, JTokenType.Integer)]
|
||||
//[InlineData(ReplaceNodeOptions.Bool, JTokenType.String)]
|
||||
//[InlineData(ReplaceNodeOptions.Integer, JTokenType.Integer)]
|
||||
//[InlineData(ReplaceNodeOptions.Bool | ReplaceNodeOptions.Integer, JTokenType.Integer)]
|
||||
[InlineData(ReplaceNodeOptions.EvaluateAndTryToConvert, JTokenType.Integer)]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate, JTokenType.String)]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_Random1_Integer(ReplaceNodeOptions options, JTokenType expected)
|
||||
{
|
||||
// Assign
|
||||
@@ -98,12 +96,14 @@ public class ResponseWithHandlebarsRandomTests
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Value"].Type).IsEqualTo(expected);
|
||||
var jObject = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
jObject["Value"]!.Type.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_Random1_Guid()
|
||||
[Theory]
|
||||
[InlineData(ReplaceNodeOptions.EvaluateAndTryToConvert, JTokenType.Guid)]
|
||||
[InlineData(ReplaceNodeOptions.Evaluate, JTokenType.String)]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_Random1_Guid(ReplaceNodeOptions options, JTokenType expected)
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
@@ -114,17 +114,15 @@ public class ResponseWithHandlebarsRandomTests
|
||||
Guid1 = "{{Random Type=\"Guid\" Uppercase=false}}",
|
||||
Guid2 = "{{Random Type=\"Guid\"}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
.WithTransformer(options);
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
string guid1 = j["Guid1"].Value<string>();
|
||||
Check.That(guid1.ToUpper()).IsNotEqualTo(guid1);
|
||||
string guid2 = j["Guid2"].Value<string>();
|
||||
Check.That(guid2.ToUpper()).IsEqualTo(guid2);
|
||||
var jObject = JObject.FromObject(response.Message.BodyData!.BodyAsJson!);
|
||||
jObject["Guid1"]!.Type.Should().Be(expected);
|
||||
jObject["Guid2"]!.Type.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -500,34 +500,6 @@ public class ResponseWithTransformerTests
|
||||
JsonConvert.SerializeObject(response.Message.BodyData!.BodyAsJson).Should().Be("[{\"x\":\"test\"}]");
|
||||
}
|
||||
|
||||
//[Theory]
|
||||
//[InlineData(TransformerType.Handlebars, "a")]
|
||||
//[InlineData(TransformerType.Handlebars, "42")]
|
||||
//[InlineData(TransformerType.Handlebars, "{")]
|
||||
//[InlineData(TransformerType.Handlebars, "]")]
|
||||
//[InlineData(TransformerType.Handlebars, " ")]
|
||||
//public async Task Response_ProvideResponse_Transformer_WithBodyAsJsonWithExtraQuotes_AndSpecialOption_MakesAString_ResultAsObject(TransformerType transformerType, string text)
|
||||
//{
|
||||
// string jsonString = $"{{ \"x\": \"{text}\" }}";
|
||||
// var bodyData = new BodyData
|
||||
// {
|
||||
// BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
// DetectedBodyType = BodyType.Json,
|
||||
// Encoding = Encoding.UTF8
|
||||
// };
|
||||
// var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
// var responseBuilder = Response.Create()
|
||||
// .WithBodyAsJson(new { text = "\"{{request.bodyAsJson.x}}\"" })
|
||||
// .WithTransformer(transformerType, false, ReplaceNodeOptions.Default);
|
||||
|
||||
// // Act
|
||||
// var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// // Assert
|
||||
// JsonConvert.SerializeObject(response.Message.BodyData.BodyAsJson).Should().Be($"{{\"text\":\"{text}\"}}");
|
||||
//}
|
||||
|
||||
[Theory]
|
||||
[InlineData(TransformerType.Handlebars, "\"\"", "\"\"")]
|
||||
[InlineData(TransformerType.Handlebars, "\"a\"", "\"a\"")]
|
||||
@@ -543,7 +515,7 @@ public class ResponseWithTransformerTests
|
||||
[InlineData(TransformerType.Handlebars, "2147483647", "2147483647")]
|
||||
[InlineData(TransformerType.Handlebars, "\"9223372036854775807\"", "\"9223372036854775807\"")]
|
||||
[InlineData(TransformerType.Handlebars, "9223372036854775807", "9223372036854775807")]
|
||||
public async Task Response_ProvideResponse_Transformer_WithBodyAsJson_And_ReplaceNodeOptionsKeep(TransformerType transformerType, string value, string expected)
|
||||
public async Task Response_ProvideResponse_Transformer_WithBodyAsJson_And_ReplaceNodeOptionsEvaluate(TransformerType transformerType, string value, string expected)
|
||||
{
|
||||
string jsonString = $"{{ \"x\": {value} }}";
|
||||
var bodyData = new BodyData
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
UseTransformer: true,
|
||||
TransformerType: Handlebars,
|
||||
TransformerReplaceNodeOptions: Evaluate
|
||||
TransformerReplaceNodeOptions: EvaluateAndTryToConvert
|
||||
},
|
||||
UseWebhooksFireAndForget: false
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
DetectedBodyType: String,
|
||||
DetectedBodyTypeFromContentType: Bytes
|
||||
},
|
||||
UseTransformer: true,
|
||||
TransformerReplaceNodeOptions: Evaluate
|
||||
UseTransformer: true
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using CultureAwareTesting.xUnit;
|
||||
using FluentAssertions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Util;
|
||||
@@ -7,6 +9,179 @@ namespace WireMock.Net.Tests.Util;
|
||||
|
||||
public class StringUtilsTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("", "")]
|
||||
[InlineData("x", "x")]
|
||||
public void TryConvertToString_ShouldWorkCorrectly(string input, string expectedValue)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(false);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<bool>().And.Be(expectedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("true", true, true)]
|
||||
[InlineData("false", false, true)]
|
||||
[InlineData("not a bool", false, false)] // Invalid case
|
||||
public void TryConvertToBool_ShouldWorkCorrectly(string input, bool expectedValue, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<bool>().And.Be(expectedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("123", 123, true)]
|
||||
[InlineData("-456", -456, true)]
|
||||
[InlineData("not an int", 0, false)] // Invalid case
|
||||
public void TryConvertToInt_ShouldWorkCorrectly(string input, int expectedValue, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<int>().And.Be(expectedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("12345678901", 12345678901L, true)]
|
||||
[InlineData("-9876543210", -9876543210L, true)]
|
||||
[InlineData("not a long", 0L, false)] // Invalid case
|
||||
public void TryConvertToLong_ShouldWorkCorrectly(string input, long expectedValue, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<long>().And.Be(expectedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[CulturedTheory("en-US")]
|
||||
[InlineData("123.1", 123.1, true)]
|
||||
[InlineData("-456.1", -456.1, true)]
|
||||
[InlineData("not a double", 0.0, false)] // Invalid case
|
||||
public void TryConvertToDouble_ShouldWorkCorrectly(string input, double expectedValue, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
((double) convertedValue).Should().BeApproximately(expectedValue, 0.01);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("3F2504E0-4F89-11D3-9A0C-0305E82C3301", true)]
|
||||
[InlineData("00000000-0000-0000-0000-000000000000", true)]
|
||||
[InlineData("3f2504e0-4f89-11d3-9a0c-0305e82c3301", true)] // Lowercase Guid
|
||||
[InlineData("not a guid", false)] // Invalid case
|
||||
public void TryConvertToGuid_ShouldWorkCorrectly(string input, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<Guid>();
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("2023-04-01", true)]
|
||||
[InlineData("01/01/2000", true)]
|
||||
[InlineData("not a date", false)] // Invalid case
|
||||
public void TryConvertToDateTime_ShouldWorkCorrectly(string input, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<DateTime>().And.Subject.As<DateTime>().Date.Should().Be(DateTime.Parse(input).Date);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("1.00:00:00", true)] // 1 day
|
||||
[InlineData("00:30:00", true)] // 30 minutes
|
||||
[InlineData("not a timespan", false)] // Invalid case
|
||||
public void TryConvertToTimeSpan_ShouldWorkCorrectly(string input, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<TimeSpan>().And.Subject.As<TimeSpan>().Should().Be(TimeSpan.Parse(input));
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("http://example.com", true)]
|
||||
[InlineData("https://example.com/path?query=string#fragment", true)]
|
||||
[InlineData("ftp://example.com", true)]
|
||||
[InlineData("file://example.com", false)]
|
||||
[InlineData("not a uri", false)] // Invalid case
|
||||
public void TryConvertToUri_ShouldWorkCorrectly(string input, bool expectedConversion)
|
||||
{
|
||||
var (isConverted, convertedValue) = StringUtils.TryConvertToKnownType(input);
|
||||
|
||||
isConverted.Should().Be(expectedConversion);
|
||||
if (isConverted)
|
||||
{
|
||||
convertedValue.Should().BeOfType<Uri>().And.Subject.As<Uri>().AbsoluteUri.Should().Be(new Uri(input).AbsoluteUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
convertedValue.Should().Be(input);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("And", MatchOperator.And)]
|
||||
[InlineData("Or", MatchOperator.Or)]
|
||||
|
||||
Reference in New Issue
Block a user