diff --git a/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs b/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs
index e9f4eccd..602d0cb1 100644
--- a/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs
+++ b/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs
@@ -1,82 +1,92 @@
using System.Text.RegularExpressions;
using WireMock.Handlers;
+using WireMock.Types;
-namespace WireMock.Admin.Settings
+namespace WireMock.Admin.Settings;
+
+///
+/// Settings
+///
+[FluentBuilder.AutoGenerateBuilder]
+public class SettingsModel
{
///
- /// Settings
+ /// Gets or sets the global delay in milliseconds.
///
- [FluentBuilder.AutoGenerateBuilder]
- public class SettingsModel
- {
- ///
- /// Gets or sets the global delay in milliseconds.
- ///
- public int? GlobalProcessingDelay { get; set; }
+ public int? GlobalProcessingDelay { get; set; }
- ///
- /// Gets or sets if partial mapping is allowed.
- ///
- public bool? AllowPartialMapping { get; set; }
+ ///
+ /// Gets or sets if partial mapping is allowed.
+ ///
+ public bool? AllowPartialMapping { get; set; }
- ///
- /// Gets or sets the RequestLog expiration in hours
- ///
- public int? RequestLogExpirationDuration { get; set; }
+ ///
+ /// Gets or sets the RequestLog expiration in hours
+ ///
+ public int? RequestLogExpirationDuration { get; set; }
- ///
- /// Gets or sets the MaxRequestLog count.
- ///
- public int? MaxRequestLogCount { get; set; }
+ ///
+ /// Gets or sets the MaxRequestLog count.
+ ///
+ public int? MaxRequestLogCount { get; set; }
- ///
- /// Allow a Body for all HTTP Methods. (default set to false).
- ///
- public bool? AllowBodyForAllHttpMethods { get; set; }
+ ///
+ /// Allow a Body for all HTTP Methods. (default set to false).
+ ///
+ public bool? AllowBodyForAllHttpMethods { get; set; }
- ///
- /// Handle all requests synchronously. (default set to false).
- ///
- public bool? HandleRequestsSynchronously { get; set; }
+ ///
+ /// Handle all requests synchronously. (default set to false).
+ ///
+ public bool? HandleRequestsSynchronously { get; set; }
- ///
- /// Throw an exception when the Matcher fails because of invalid input. (default set to false).
- ///
- public bool? ThrowExceptionWhenMatcherFails { get; set; }
+ ///
+ /// Throw an exception when the Matcher fails because of invalid input. (default set to false).
+ ///
+ public bool? ThrowExceptionWhenMatcherFails { get; set; }
- ///
- /// Use the RegexExtended instead of the default . (default set to true).
- ///
- public bool? UseRegexExtended { get; set; }
+ ///
+ /// Use the RegexExtended instead of the default . (default set to true).
+ ///
+ public bool? UseRegexExtended { get; set; }
- ///
- /// Save unmatched requests to a file using the . (default set to false).
- ///
- public bool? SaveUnmatchedRequests { get; set; }
+ ///
+ /// Save unmatched requests to a file using the . (default set to false).
+ ///
+ public bool? SaveUnmatchedRequests { get; set; }
- ///
- /// Gets or sets if the static mappings should be read at startup.
- ///
- public bool? ReadStaticMappings { get; set; }
+ ///
+ /// Gets or sets if the static mappings should be read at startup.
+ ///
+ public bool? ReadStaticMappings { get; set; }
- ///
- /// Watch the static mapping files + folder for changes when running.
- ///
- public bool? WatchStaticMappings { get; set; }
+ ///
+ /// Watch the static mapping files + folder for changes when running.
+ ///
+ public bool? WatchStaticMappings { get; set; }
- ///
- /// A value indicating whether subdirectories within the static mappings path should be monitored.
- ///
- public bool? WatchStaticMappingsInSubdirectories { get; set; }
+ ///
+ /// A value indicating whether subdirectories within the static mappings path should be monitored.
+ ///
+ public bool? WatchStaticMappingsInSubdirectories { get; set; }
- ///
- /// Policies to use when using CORS. By default CORS is disabled. [Optional]
- ///
- public string? CorsPolicyOptions { get; set; }
+ ///
+ /// Policies to use when using CORS. By default CORS is disabled. [Optional]
+ ///
+ public string? CorsPolicyOptions { get; set; }
- ///
- /// The proxy and record settings.
- ///
- public ProxyAndRecordSettingsModel? ProxyAndRecordSettings { get; set; }
- }
+ ///
+ /// The proxy and record settings.
+ ///
+ public ProxyAndRecordSettingsModel? ProxyAndRecordSettings { get; set; }
+
+ ///
+ /// Defines on which scheme (http/https) to host. (This overrides the UseSSL value).
+ ///
+ public HostingScheme? HostingScheme { get; set; }
+
+ ///
+ /// Don't save the response-string in the LogEntry when WithBody(Func{IRequestMessage, string}) or WithBody(Func{IRequestMessage, Task{string}}) is used. (default set to false).
+ ///
+ public bool? DoNotSaveDynamicResponseInLogEntry { get; set; }
}
\ No newline at end of file
diff --git a/src/WireMock.Net.Abstractions/Models/IBodyData.cs b/src/WireMock.Net.Abstractions/Models/IBodyData.cs
index 38912666..faafd2c0 100644
--- a/src/WireMock.Net.Abstractions/Models/IBodyData.cs
+++ b/src/WireMock.Net.Abstractions/Models/IBodyData.cs
@@ -1,6 +1,4 @@
-using System.Diagnostics.CodeAnalysis;
using System.Text;
-using JetBrains.Annotations;
using WireMock.Types;
namespace WireMock.Util;
@@ -59,4 +57,9 @@ public interface IBodyData
/// The body encoding.
///
Encoding? Encoding { get; set; }
+
+ ///
+ /// Defines if this BodyData is the result of a dynamically created response-string. (
+ ///
+ public string? IsFuncUsed { get; set; }
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Logging/LogEntry.cs b/src/WireMock.Net/Logging/LogEntry.cs
index 4be2861c..a5b556d1 100644
--- a/src/WireMock.Net/Logging/LogEntry.cs
+++ b/src/WireMock.Net/Logging/LogEntry.cs
@@ -12,13 +12,13 @@ public class LogEntry : ILogEntry
public Guid Guid { get; set; }
///
- public IRequestMessage RequestMessage { get; set; }
+ public IRequestMessage RequestMessage { get; set; } = null!;
///
- public IResponseMessage ResponseMessage { get; set; }
+ public IResponseMessage ResponseMessage { get; set; } = null!;
///
- public IRequestMatchResult RequestMatchResult { get; set; }
+ public IRequestMatchResult RequestMatchResult { get; set; } = null!;
///
public Guid? MappingGuid { get; set; }
@@ -33,5 +33,5 @@ public class LogEntry : ILogEntry
public string? PartialMappingTitle { get; set; }
///
- public IRequestMatchResult PartialMatchResult { get; set; }
+ public IRequestMatchResult PartialMatchResult { get; set; } = null!;
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Matchers/LinqMatcher.cs b/src/WireMock.Net/Matchers/LinqMatcher.cs
index ec41f79c..80167b8c 100644
--- a/src/WireMock.Net/Matchers/LinqMatcher.cs
+++ b/src/WireMock.Net/Matchers/LinqMatcher.cs
@@ -21,6 +21,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
///
public MatchBehaviour MatchBehaviour { get; }
+
///
public bool ThrowException { get; }
diff --git a/src/WireMock.Net/Models/BodyData.cs b/src/WireMock.Net/Models/BodyData.cs
index d9640637..7d00e971 100644
--- a/src/WireMock.Net/Models/BodyData.cs
+++ b/src/WireMock.Net/Models/BodyData.cs
@@ -1,41 +1,43 @@
using System.Text;
using WireMock.Types;
-namespace WireMock.Util
+namespace WireMock.Util;
+
+///
+/// BodyData
+///
+public class BodyData : IBodyData
{
- ///
- /// BodyData
- ///
- public class BodyData : IBodyData
- {
- ///
- public Encoding? Encoding { get; set; }
+ ///
+ public Encoding? Encoding { get; set; }
- ///
- public string? BodyAsString { get; set; }
+ ///
+ public string? BodyAsString { get; set; }
- ///
- public object? BodyAsJson { get; set; }
+ ///
+ public object? BodyAsJson { get; set; }
- ///
- public byte[]? BodyAsBytes { get; set; }
+ ///
+ public byte[]? BodyAsBytes { get; set; }
- ///
- public bool? BodyAsJsonIndented { get; set; }
+ ///
+ public bool? BodyAsJsonIndented { get; set; }
- ///
- public string? BodyAsFile { get; set; }
+ ///
+ public string? BodyAsFile { get; set; }
- ///
- public bool? BodyAsFileIsCached { get; set; }
+ ///
+ public bool? BodyAsFileIsCached { get; set; }
- ///
- public BodyType? DetectedBodyType { get; set; }
+ ///
+ public BodyType? DetectedBodyType { get; set; }
- ///
- public BodyType? DetectedBodyTypeFromContentType { get; set; }
+ ///
+ public BodyType? DetectedBodyTypeFromContentType { get; set; }
- ///
- public string? DetectedCompression { get; set; }
- }
+ ///
+ public string? DetectedCompression { get; set; }
+
+ ///
+ public string? IsFuncUsed { get; set; }
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs
index 1594bfcd..929e3994 100644
--- a/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs
+++ b/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs
@@ -69,4 +69,6 @@ internal interface IWireMockMiddlewareOptions
bool CustomCertificateDefined { get; }
bool? SaveUnmatchedRequests { get; set; }
+
+ public bool? DoNotSaveDynamicResponseInLogEntry { get; set; }
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Owin/WireMockMiddleware.cs b/src/WireMock.Net/Owin/WireMockMiddleware.cs
index 23445942..d78d4a35 100644
--- a/src/WireMock.Net/Owin/WireMockMiddleware.cs
+++ b/src/WireMock.Net/Owin/WireMockMiddleware.cs
@@ -32,22 +32,25 @@ namespace WireMock.Owin
private readonly IOwinRequestMapper _requestMapper;
private readonly IOwinResponseMapper _responseMapper;
private readonly IMappingMatcher _mappingMatcher;
+ private readonly LogEntryMapper _logEntryMapper;
#if !USE_ASPNETCORE
public WireMockMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinRequestMapper requestMapper, IOwinResponseMapper responseMapper, IMappingMatcher mappingMatcher) : base(next)
{
- _options = Guard.NotNull(options, nameof(options));
- _requestMapper = Guard.NotNull(requestMapper, nameof(requestMapper));
- _responseMapper = Guard.NotNull(responseMapper, nameof(responseMapper));
- _mappingMatcher = Guard.NotNull(mappingMatcher, nameof(mappingMatcher));
+ _options = Guard.NotNull(options);
+ _requestMapper = Guard.NotNull(requestMapper);
+ _responseMapper = Guard.NotNull(responseMapper);
+ _mappingMatcher = Guard.NotNull(mappingMatcher);
+ _logEntryMapper = new LogEntryMapper(options);
}
#else
public WireMockMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinRequestMapper requestMapper, IOwinResponseMapper responseMapper, IMappingMatcher mappingMatcher)
{
- _options = Guard.NotNull(options, nameof(options));
- _requestMapper = Guard.NotNull(requestMapper, nameof(requestMapper));
- _responseMapper = Guard.NotNull(responseMapper, nameof(responseMapper));
- _mappingMatcher = Guard.NotNull(mappingMatcher, nameof(mappingMatcher));
+ _options = Guard.NotNull(options);
+ _requestMapper = Guard.NotNull(requestMapper);
+ _responseMapper = Guard.NotNull(responseMapper);
+ _mappingMatcher = Guard.NotNull(mappingMatcher);
+ _logEntryMapper = new LogEntryMapper(options);
}
#endif
@@ -264,7 +267,7 @@ namespace WireMock.Owin
private void LogRequest(LogEntry entry, bool addRequest)
{
- _options.Logger.DebugRequestResponse(LogEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__admin/"));
+ _options.Logger.DebugRequestResponse(_logEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__admin/"));
if (addRequest)
{
diff --git a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
index fffdfde9..568d1bd1 100644
--- a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
+++ b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs
@@ -84,4 +84,7 @@ internal class WireMockMiddlewareOptions : IWireMockMiddlewareOptions
///
public bool? SaveUnmatchedRequests { get; set; }
+
+ ///
+ public bool? DoNotSaveDynamicResponseInLogEntry { get; set; }
}
\ No newline at end of file
diff --git a/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs b/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
index a73f4a8c..852eafa1 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
@@ -21,7 +21,8 @@ public partial class Response
{
DetectedBodyType = BodyType.String,
BodyAsString = bodyFactory(req),
- Encoding = encoding ?? Encoding.UTF8
+ Encoding = encoding ?? Encoding.UTF8,
+ IsFuncUsed = "Func"
}
});
}
@@ -37,7 +38,8 @@ public partial class Response
{
DetectedBodyType = BodyType.String,
BodyAsString = await bodyFactory(req).ConfigureAwait(false),
- Encoding = encoding ?? Encoding.UTF8
+ Encoding = encoding ?? Encoding.UTF8,
+ IsFuncUsed = "Func>"
}
});
}
diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs
index 536feb87..23221f8a 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.cs
@@ -325,15 +325,15 @@ public partial class Response : IResponseBuilder
break;
default:
- throw new NotImplementedException($"TransformerType '{TransformerType}' is not supported.");
+ throw new NotSupportedException($"TransformerType '{TransformerType}' is not supported.");
}
return (responseMessageTransformer.Transform(mapping, requestMessage, responseMessage, UseTransformerForBodyAsFile, TransformerReplaceNodeOptions), null);
}
- if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
+ if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true && responseMessage.BodyData?.BodyAsFile is not null)
{
- ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData!.BodyAsFile);
+ ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
}
return (responseMessage, null);
diff --git a/src/WireMock.Net/Serialization/LogEntryMapper.cs b/src/WireMock.Net/Serialization/LogEntryMapper.cs
index 6f9d9c81..d2dfe243 100644
--- a/src/WireMock.Net/Serialization/LogEntryMapper.cs
+++ b/src/WireMock.Net/Serialization/LogEntryMapper.cs
@@ -1,16 +1,25 @@
using System.Linq;
+using Stef.Validation;
using WireMock.Admin.Mappings;
using WireMock.Admin.Requests;
using WireMock.Logging;
using WireMock.Matchers.Request;
+using WireMock.Owin;
using WireMock.ResponseBuilders;
using WireMock.Types;
namespace WireMock.Serialization;
-internal static class LogEntryMapper
+internal class LogEntryMapper
{
- public static LogEntryModel Map(ILogEntry logEntry)
+ private readonly IWireMockMiddlewareOptions _options;
+
+ public LogEntryMapper(IWireMockMiddlewareOptions options)
+ {
+ _options = Guard.NotNull(options);
+ }
+
+ public LogEntryModel Map(ILogEntry logEntry)
{
var logRequestModel = new LogRequestModel
{
@@ -78,25 +87,7 @@ internal static class LogEntryMapper
logResponseModel.DetectedBodyType = logEntry.ResponseMessage.BodyData.DetectedBodyType;
logResponseModel.DetectedBodyTypeFromContentType = logEntry.ResponseMessage.BodyData.DetectedBodyTypeFromContentType;
- switch (logEntry.ResponseMessage.BodyData.DetectedBodyType)
- {
- case BodyType.String:
- logResponseModel.Body = logEntry.ResponseMessage.BodyData.BodyAsString;
- break;
-
- case BodyType.Json:
- logResponseModel.BodyAsJson = logEntry.ResponseMessage.BodyData.BodyAsJson;
- break;
-
- case BodyType.Bytes:
- logResponseModel.BodyAsBytes = logEntry.ResponseMessage.BodyData.BodyAsBytes;
- break;
-
- case BodyType.File:
- logResponseModel.BodyAsFile = logEntry.ResponseMessage.BodyData.BodyAsFile;
- logResponseModel.BodyAsFileIsCached = logEntry.ResponseMessage.BodyData.BodyAsFileIsCached;
- break;
- }
+ MapBody(logEntry, logResponseModel);
logResponseModel.BodyEncoding = logEntry.ResponseMessage.BodyData.Encoding != null
? new EncodingModel
@@ -124,6 +115,36 @@ internal static class LogEntryMapper
};
}
+ private void MapBody(ILogEntry logEntry, LogResponseModel logResponseModel)
+ {
+ switch (logEntry.ResponseMessage.BodyData!.DetectedBodyType)
+ {
+ case BodyType.String:
+ if (!string.IsNullOrEmpty(logEntry.ResponseMessage.BodyData.IsFuncUsed) && _options.DoNotSaveDynamicResponseInLogEntry == true)
+ {
+ logResponseModel.Body = logEntry.ResponseMessage.BodyData.IsFuncUsed;
+ }
+ else
+ {
+ logResponseModel.Body = logEntry.ResponseMessage.BodyData.BodyAsString;
+ }
+ break;
+
+ case BodyType.Json:
+ logResponseModel.BodyAsJson = logEntry.ResponseMessage.BodyData.BodyAsJson;
+ break;
+
+ case BodyType.Bytes:
+ logResponseModel.BodyAsBytes = logEntry.ResponseMessage.BodyData.BodyAsBytes;
+ break;
+
+ case BodyType.File:
+ logResponseModel.BodyAsFile = logEntry.ResponseMessage.BodyData.BodyAsFile;
+ logResponseModel.BodyAsFileIsCached = logEntry.ResponseMessage.BodyData.BodyAsFileIsCached;
+ break;
+ }
+ }
+
private static LogRequestMatchModel? Map(IRequestMatchResult? matchResult)
{
if (matchResult == null)
diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs
index 2609a554..f8399fca 100644
--- a/src/WireMock.Net/Server/WireMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs
@@ -277,6 +277,8 @@ public partial class WireMockServer
UseRegexExtended = _settings.UseRegexExtended,
WatchStaticMappings = _settings.WatchStaticMappings,
WatchStaticMappingsInSubdirectories = _settings.WatchStaticMappingsInSubdirectories,
+ HostingScheme = _settings.HostingScheme,
+ DoNotSaveDynamicResponseInLogEntry = _settings.DoNotSaveDynamicResponseInLogEntry,
#if USE_ASPNETCORE
CorsPolicyOptions = _settings.CorsPolicyOptions?.ToString()
@@ -305,6 +307,7 @@ public partial class WireMockServer
_settings.UseRegexExtended = settings.UseRegexExtended;
_settings.WatchStaticMappings = settings.WatchStaticMappings;
_settings.WatchStaticMappingsInSubdirectories = settings.WatchStaticMappingsInSubdirectories;
+ _settings.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry;
InitSettings(_settings);
@@ -525,7 +528,7 @@ public partial class WireMockServer
return ResponseMessageBuilder.Create("Request not found", 404);
}
- var model = LogEntryMapper.Map(entry);
+ var model = new LogEntryMapper(_options).Map(entry);
return ToJson(model);
}
@@ -546,9 +549,10 @@ public partial class WireMockServer
#region Requests
private IResponseMessage RequestsGet(IRequestMessage requestMessage)
{
+ var logEntryMapper = new LogEntryMapper(_options);
var result = LogEntries
.Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
- .Select(LogEntryMapper.Map);
+ .Select(logEntryMapper.Map);
return ToJson(result);
}
@@ -578,7 +582,8 @@ public partial class WireMockServer
}
}
- var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(LogEntryMapper.Map);
+ var logEntryMapper = new LogEntryMapper(_options);
+ var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(logEntryMapper.Map);
return ToJson(result);
}
diff --git a/src/WireMock.Net/Server/WireMockServer.cs b/src/WireMock.Net/Server/WireMockServer.cs
index cb6248f9..77efceb3 100644
--- a/src/WireMock.Net/Server/WireMockServer.cs
+++ b/src/WireMock.Net/Server/WireMockServer.cs
@@ -295,6 +295,7 @@ public partial class WireMockServer : IWireMockServer
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
_options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
+ _options.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry;
if (settings.CustomCertificateDefined)
{
diff --git a/src/WireMock.Net/Settings/WireMockServerSettings.cs b/src/WireMock.Net/Settings/WireMockServerSettings.cs
index f8b36585..4b525fd2 100644
--- a/src/WireMock.Net/Settings/WireMockServerSettings.cs
+++ b/src/WireMock.Net/Settings/WireMockServerSettings.cs
@@ -252,6 +252,12 @@ namespace WireMock.Settings
[PublicAPI]
public bool? SaveUnmatchedRequests { get; set; }
+ ///
+ /// Don't save the response-string in the LogEntry when WithBody(Func{IRequestMessage, string}) or WithBody(Func{IRequestMessage, Task{string}}) is used. (default set to false).
+ ///
+ [PublicAPI]
+ public bool? DoNotSaveDynamicResponseInLogEntry { get; set; }
+
///
/// Custom matcher mappings for static mappings
///
diff --git a/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs b/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs
index 32fecedb..3f875998 100644
--- a/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs
+++ b/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs
@@ -54,7 +54,8 @@ public static class WireMockServerSettingsParser
UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true),
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
WatchStaticMappingsInSubdirectories = parser.GetBoolValue("WatchStaticMappingsInSubdirectories"),
- HostingScheme = parser.GetEnumValue(nameof(WireMockServerSettings.HostingScheme))
+ HostingScheme = parser.GetEnumValue(nameof(WireMockServerSettings.HostingScheme)),
+ DoNotSaveDynamicResponseInLogEntry = parser.GetBoolValue(nameof(WireMockServerSettings.DoNotSaveDynamicResponseInLogEntry))
};
#if USE_ASPNETCORE
diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs
index 81b083c5..e3702f95 100644
--- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs
+++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs
@@ -21,12 +21,12 @@ public class ResponseWithBodyTests
private readonly Mock _mappingMock;
private readonly Mock _filesystemHandlerMock;
- private readonly WireMockServerSettings _settings = new ();
+ private readonly WireMockServerSettings _settings = new();
public ResponseWithBodyTests()
{
_mappingMock = new Mock();
-
+
_filesystemHandlerMock = new Mock(MockBehavior.Strict);
_filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny())).Returns("abc");
@@ -197,61 +197,7 @@ public class ResponseWithBodyTests
}
[Fact]
- public async Task Response_ProvideResponse_WithBody_Func()
- {
- // Assign
- var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
-
- var responseBuilder = Response.Create()
- .WithStatusCode(500)
- .WithHeader("H1", "X1")
- .WithHeader("H2", "X2")
- .WithBody(req => $"path: {req.Path}");
-
- // Act
- var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
-
- // Assert
- Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test");
- Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
- Check.That(response.Message.BodyData.BodyAsJson).IsNull();
- Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
- Check.That(response.Message.StatusCode).IsEqualTo(500);
- Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1");
- Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2");
- }
-
- [Fact]
- public async Task Response_ProvideResponse_WithBody_FuncAsync()
- {
- // Assign
- var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
-
- var responseBuilder = Response.Create()
- .WithStatusCode(500)
- .WithHeader("H1", "X1")
- .WithHeader("H2", "X2")
- .WithBody(async req =>
- {
- await Task.Delay(1).ConfigureAwait(false);
- return $"path: {req.Path}";
- });
-
- // Act
- var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
-
- // Assert
- Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test");
- Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
- Check.That(response.Message.BodyData.BodyAsJson).IsNull();
- Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
- Check.That(response.Message.StatusCode).IsEqualTo(500);
- Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1");
- Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2");
- }
-
- [Fact]
- public async Task Response_ProvideResponse_WithJsonBodyAndTransform_Func()
+ public async Task Response_ProvideResponse_WithJsonBodyAndTransform()
{
// Assign
const int request1Id = 1;
diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithCallbackTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithCallbackTests.cs
index ac1413a8..97806713 100644
--- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithCallbackTests.cs
+++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithCallbackTests.cs
@@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Net;
+using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Moq;
+using NFluent;
using WireMock.Handlers;
using WireMock.Models;
using WireMock.ResponseBuilders;
@@ -18,17 +20,124 @@ public class ResponseWithCallbackTests
private const string ClientIp = "::1";
private readonly Mock _mappingMock;
- private readonly Mock _filesystemHandlerMock;
private readonly WireMockServerSettings _settings = new();
public ResponseWithCallbackTests()
{
_mappingMock = new Mock();
- _filesystemHandlerMock = new Mock(MockBehavior.Strict);
- _filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny())).Returns("abc");
+ var filesystemHandlerMock = new Mock(MockBehavior.Strict);
+ filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny())).Returns("abc");
- _settings.FileSystemHandler = _filesystemHandlerMock.Object;
+ _settings.FileSystemHandler = filesystemHandlerMock.Object;
+ }
+
+ [Fact]
+ public async Task Response_ProvideResponse_WithBody_Func()
+ {
+ // Assign
+ var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
+
+ var responseBuilder = Response.Create()
+ .WithStatusCode(500)
+ .WithHeader("H1", "X1")
+ .WithHeader("H2", "X2")
+ .WithBody(req => $"path: {req.Path}");
+
+ // Act
+ var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
+
+ // Assert
+ Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test");
+ Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
+ Check.That(response.Message.BodyData.BodyAsJson).IsNull();
+ Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
+ Check.That(response.Message.StatusCode).IsEqualTo(500);
+ Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1");
+ Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2");
+ }
+
+ [Fact]
+ public async Task Response_ProvideResponse_WithBody_Func_DynamicCode_Should_IsFuncUsed()
+ {
+ // Assign
+ var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
+
+ var data = new[] { "x", "y" };
+ var i = 0;
+ var responseBuilder = Response.Create()
+ .WithBody(_ =>
+ {
+ var value = data[i];
+ i++;
+ return value;
+ });
+
+ // Act (2x)
+ var response1 = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
+ var response2 = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
+
+ // Assert
+ response1.Message.BodyData!.BodyAsString.Should().Be("x");
+ response1.Message.BodyData!.IsFuncUsed.Should().Be("Func");
+ response2.Message.BodyData!.BodyAsString.Should().Be("y");
+ response2.Message.BodyData!.IsFuncUsed.Should().Be("Func");
+ }
+
+ [Fact]
+ public async Task Response_ProvideResponse_WithBody_AsyncFunc_DynamicCode_Should_IsFuncUsed()
+ {
+ // Assign
+ var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
+
+ var data = new[] { "x", "y" };
+ var i = 0;
+ var responseBuilder = Response.Create()
+ .WithBody(_ =>
+ {
+ var value = data[i];
+ i++;
+ return Task.FromResult(value);
+ });
+
+ // Act (2x)
+ var response1 = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
+ var response2 = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
+
+ // Assert
+ response1.Message.BodyData!.BodyAsString.Should().Be("x");
+ response1.Message.BodyData!.IsFuncUsed.Should().Be("Func>");
+ response2.Message.BodyData!.BodyAsString.Should().Be("y");
+ response2.Message.BodyData!.IsFuncUsed.Should().Be("Func>");
+ }
+
+ [Fact]
+ public async Task Response_ProvideResponse_WithBody_FuncAsync()
+ {
+ // Assign
+ var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
+
+ var responseBuilder = Response.Create()
+ .WithStatusCode(500)
+ .WithHeader("H1", "X1")
+ .WithHeader("H2", "X2")
+ .WithBody(async req =>
+ {
+ await Task.Delay(1).ConfigureAwait(false);
+ return $"path: {req.Path}";
+ });
+
+ // Act
+ var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
+
+ // Assert
+ Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test");
+ Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
+ Check.That(response.Message.BodyData.BodyAsJson).IsNull();
+ Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
+ Check.That(response.Message.StatusCode).IsEqualTo(500);
+ Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1");
+ Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2");
}
[Fact]
diff --git a/test/WireMock.Net.Tests/Serialization/LogEntryMapperTests.cs b/test/WireMock.Net.Tests/Serialization/LogEntryMapperTests.cs
index 59bc86fc..76b46e99 100644
--- a/test/WireMock.Net.Tests/Serialization/LogEntryMapperTests.cs
+++ b/test/WireMock.Net.Tests/Serialization/LogEntryMapperTests.cs
@@ -2,6 +2,7 @@ using FluentAssertions;
using NFluent;
using WireMock.Logging;
using WireMock.Models;
+using WireMock.Owin;
using WireMock.ResponseBuilders;
using WireMock.Serialization;
using WireMock.Types;
@@ -12,6 +13,15 @@ namespace WireMock.Net.Tests.Serialization;
public class LogEntryMapperTests
{
+ private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
+
+ private readonly LogEntryMapper _sut;
+
+ public LogEntryMapperTests()
+ {
+ _sut = new LogEntryMapper(_options);
+ }
+
[Fact]
public void LogEntryMapper_Map_LogEntry_Check_BodyTypeBytes()
{
@@ -39,7 +49,7 @@ public class LogEntryMapperTests
};
// Act
- var result = LogEntryMapper.Map(logEntry);
+ var result = _sut.Map(logEntry);
// Assert
Check.That(result.Request.DetectedBodyType).IsEqualTo("Bytes");
@@ -74,7 +84,7 @@ public class LogEntryMapperTests
};
// Act
- var result = LogEntryMapper.Map(logEntry);
+ var result = _sut.Map(logEntry);
// Assert
Check.That(result.Request.DetectedBodyType).IsNull();
@@ -111,10 +121,49 @@ public class LogEntryMapperTests
};
// Act
- var result = LogEntryMapper.Map(logEntry);
+ var result = _sut.Map(logEntry);
// Assert
result.Response.FaultType.Should().Be("EMPTY_RESPONSE");
result.Response.FaultPercentage.Should().Be(0.5);
}
+
+ [Fact]
+ public void LogEntryMapper_Map_LogEntry_WhenFuncIsUsed_And_DoNotSaveDynamicResponseInLogEntry_Is_True_Should_NotSave_StringResponse()
+ {
+ // Assign
+ var options = new WireMockMiddlewareOptions
+ {
+ DoNotSaveDynamicResponseInLogEntry = true
+ };
+ var isFuncUsed = "Func";
+ var logEntry = new LogEntry
+ {
+ RequestMessage = new RequestMessage(
+ new UrlDetails("http://localhost"),
+ "post",
+ "::1",
+ new BodyData
+ {
+ DetectedBodyType = BodyType.Bytes,
+ BodyAsBytes = new byte[] { 0 }
+ }
+ ),
+ ResponseMessage = new ResponseMessage
+ {
+ BodyData = new BodyData
+ {
+ DetectedBodyType = BodyType.String,
+ BodyAsString = "test",
+ IsFuncUsed = isFuncUsed
+ }
+ }
+ };
+
+ // Act
+ var result = new LogEntryMapper(options).Map(logEntry);
+
+ // Assert
+ result.Response.Body.Should().Be(isFuncUsed);
+ }
}
\ No newline at end of file