From 1d1ff4a418c54ae634820781380a7ff312770d08 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Fri, 24 Dec 2021 09:34:26 +0100 Subject: [PATCH] SaveUnmatchedRequests (#703) --- WireMock.Net Solution.sln.DotSettings | 1 + .../CustomFileSystemFileHandler.cs | 16 +++++ .../Run.cs | 3 +- .../Admin/Settings/SettingsModel.cs | 15 ++++- .../Handlers/IFileSystemHandler.cs | 13 ++++ .../Handlers/LocalFileSystemHandler.cs | 60 +++++++++++++------ .../Owin/IWireMockMiddlewareOptions.cs | 3 + .../Owin/Mappers/OwinRequestMapper.cs | 6 +- src/WireMock.Net/Owin/WireMockMiddleware.cs | 52 ++++++++-------- .../Owin/WireMockMiddlewareOptions.cs | 5 +- .../JsonSerializationConstants.cs | 7 ++- .../Server/WireMockServer.Admin.cs | 31 +++------- src/WireMock.Net/Server/WireMockServer.cs | 1 + .../Settings/IWireMockServerSettings.cs | 12 +++- .../Settings/WireMockServerSettings.cs | 5 +- .../Settings/WireMockServerSettingsParser.cs | 3 +- src/WireMock.Net/Util/JsonUtils.cs | 15 ++--- .../Handlers/LocalFileSystemHandlerTests.cs | 17 ++++++ 18 files changed, 180 insertions(+), 85 deletions(-) diff --git a/WireMock.Net Solution.sln.DotSettings b/WireMock.Net Solution.sln.DotSettings index c366605a..701cb04e 100644 --- a/WireMock.Net Solution.sln.DotSettings +++ b/WireMock.Net Solution.sln.DotSettings @@ -1,4 +1,5 @@  + AD CS ID IP diff --git a/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs b/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs index 45e06730..aeeefc81 100644 --- a/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs +++ b/examples/WireMock.Net.Console.Net452.Classic/CustomFileSystemFileHandler.cs @@ -7,6 +7,7 @@ namespace WireMock.Net.ConsoleApplication internal class CustomFileSystemFileHandler : IFileSystemHandler { private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings"); + private static readonly string UnmatchedRequestsFolder = Path.Combine("requests", "unmatched"); /// public bool FolderExists(string path) @@ -86,6 +87,21 @@ namespace WireMock.Net.ConsoleApplication return File.ReadAllText(path); } + /// + public string GetUnmatchedRequestsFolder() + { + return Path.Combine(@"c:\temp-wiremock", UnmatchedRequestsFolder); + } + + /// + public void WriteUnmatchedRequest(string filename, string text) + { + var folder = GetUnmatchedRequestsFolder(); + Directory.CreateDirectory(folder); + + File.WriteAllText(Path.Combine(folder, filename), text); + } + /// /// Adjusts the path to the MappingFolder. /// diff --git a/examples/WireMock.Net.OpenApiParser.ConsoleApp/Run.cs b/examples/WireMock.Net.OpenApiParser.ConsoleApp/Run.cs index 855ddff3..207d6188 100644 --- a/examples/WireMock.Net.OpenApiParser.ConsoleApp/Run.cs +++ b/examples/WireMock.Net.OpenApiParser.ConsoleApp/Run.cs @@ -23,7 +23,8 @@ namespace WireMock.Net.OpenApiParser.ConsoleApp ReadStaticMappings = false, WatchStaticMappings = false, WatchStaticMappingsInSubdirectories = false, - Logger = new WireMockConsoleLogger() + Logger = new WireMockConsoleLogger(), + SaveUnmatchedRequests = true }); Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls)); diff --git a/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs b/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs index 85f71717..636405ad 100644 --- a/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs +++ b/src/WireMock.Net.Abstractions/Admin/Settings/SettingsModel.cs @@ -1,4 +1,7 @@ -namespace WireMock.Admin.Settings +using System.Text.RegularExpressions; +using WireMock.Handlers; + +namespace WireMock.Admin.Settings { /// /// Settings @@ -40,5 +43,15 @@ /// 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; } + + /// + /// Save unmatched requests to a file using the . (default set to false). + /// + public bool? SaveUnmatchedRequests { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net.Abstractions/Handlers/IFileSystemHandler.cs b/src/WireMock.Net.Abstractions/Handlers/IFileSystemHandler.cs index ffeb06ec..9d841a01 100644 --- a/src/WireMock.Net.Abstractions/Handlers/IFileSystemHandler.cs +++ b/src/WireMock.Net.Abstractions/Handlers/IFileSystemHandler.cs @@ -96,5 +96,18 @@ namespace WireMock.Handlers /// The filename. /// The file content as a string. string ReadFileAsString([NotNull] string filename); + + /// + /// Gets the folder where the unmatched requests should be stored. For local file system, this would be `{CurrentFolder}/requests/unmatched`. + /// + /// The folder name. + string GetUnmatchedRequestsFolder(); + + /// + /// Write a unmatched request to the Unmatched RequestsFolder. + /// + /// The filename. + /// The text. + void WriteUnmatchedRequest([NotNull] string filename, [NotNull] string text); } } \ No newline at end of file diff --git a/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs b/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs index 467701d3..1ce7ef3c 100644 --- a/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs +++ b/src/WireMock.Net/Handlers/LocalFileSystemHandler.cs @@ -11,6 +11,7 @@ namespace WireMock.Handlers public class LocalFileSystemHandler : IFileSystemHandler { private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings"); + private static readonly string UnmatchedRequestsFolder = Path.Combine("requests", "unmatched"); private readonly string _rootFolder; @@ -31,7 +32,7 @@ namespace WireMock.Handlers } /// - public bool FolderExists(string path) + public virtual bool FolderExists(string path) { Check.NotNullOrEmpty(path, nameof(path)); @@ -39,7 +40,7 @@ namespace WireMock.Handlers } /// - public void CreateFolder(string path) + public virtual void CreateFolder(string path) { Check.NotNullOrEmpty(path, nameof(path)); @@ -47,7 +48,7 @@ namespace WireMock.Handlers } /// - public IEnumerable EnumerateFiles(string path, bool includeSubdirectories) + public virtual IEnumerable EnumerateFiles(string path, bool includeSubdirectories) { Check.NotNullOrEmpty(path, nameof(path)); @@ -55,13 +56,13 @@ namespace WireMock.Handlers } /// - public string GetMappingFolder() + public virtual string GetMappingFolder() { return Path.Combine(_rootFolder, AdminMappingsFolder); } /// - public string ReadMappingFile(string path) + public virtual string ReadMappingFile(string path) { Check.NotNullOrEmpty(path, nameof(path)); @@ -69,7 +70,7 @@ namespace WireMock.Handlers } /// - public void WriteMappingFile(string path, string text) + public virtual void WriteMappingFile(string path, string text) { Check.NotNullOrEmpty(path, nameof(path)); Check.NotNull(text, nameof(text)); @@ -78,7 +79,7 @@ namespace WireMock.Handlers } /// - public byte[] ReadResponseBodyAsFile(string path) + public virtual byte[] ReadResponseBodyAsFile(string path) { Check.NotNullOrEmpty(path, nameof(path)); path = PathUtils.CleanPath(path); @@ -88,7 +89,7 @@ namespace WireMock.Handlers } /// - public string ReadResponseBodyAsString(string path) + public virtual string ReadResponseBodyAsString(string path) { Check.NotNullOrEmpty(path, nameof(path)); path = PathUtils.CleanPath(path); @@ -98,42 +99,63 @@ namespace WireMock.Handlers } /// - public bool FileExists(string filename) + public virtual bool FileExists(string filename) { Check.NotNullOrEmpty(filename, nameof(filename)); - return File.Exists(AdjustPath(filename)); + return File.Exists(AdjustPathForMappingFolder(filename)); } /// - public void WriteFile(string filename, byte[] bytes) + public virtual void WriteFile(string filename, byte[] bytes) { Check.NotNullOrEmpty(filename, nameof(filename)); Check.NotNull(bytes, nameof(bytes)); - File.WriteAllBytes(AdjustPath(filename), bytes); + File.WriteAllBytes(AdjustPathForMappingFolder(filename), bytes); } /// - public void DeleteFile(string filename) + public virtual void DeleteFile(string filename) { Check.NotNullOrEmpty(filename, nameof(filename)); - File.Delete(AdjustPath(filename)); + File.Delete(AdjustPathForMappingFolder(filename)); } /// - public byte[] ReadFile(string filename) + public virtual byte[] ReadFile(string filename) { Check.NotNullOrEmpty(filename, nameof(filename)); - return File.ReadAllBytes(AdjustPath(filename)); + return File.ReadAllBytes(AdjustPathForMappingFolder(filename)); } /// - public string ReadFileAsString(string filename) + public virtual string ReadFileAsString(string filename) { - return File.ReadAllText(AdjustPath(Check.NotNullOrEmpty(filename, nameof(filename)))); + return File.ReadAllText(AdjustPathForMappingFolder(Check.NotNullOrEmpty(filename, nameof(filename)))); + } + + /// + public virtual string GetUnmatchedRequestsFolder() + { + return Path.Combine(_rootFolder, UnmatchedRequestsFolder); + } + + /// + public virtual void WriteUnmatchedRequest(string filename, string text) + { + Check.NotNullOrEmpty(filename, nameof(filename)); + Check.NotNull(text, nameof(text)); + + var folder = GetUnmatchedRequestsFolder(); + if (!FolderExists(folder)) + { + CreateFolder(folder); + } + + File.WriteAllText(Path.Combine(folder, filename), text); } /// @@ -141,7 +163,7 @@ namespace WireMock.Handlers /// /// The path. /// Adjusted path - private string AdjustPath(string filename) + private string AdjustPathForMappingFolder(string filename) { return Path.Combine(GetMappingFolder(), filename); } diff --git a/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs index 7a3166b8..810903c7 100644 --- a/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs +++ b/src/WireMock.Net/Owin/IWireMockMiddlewareOptions.cs @@ -4,6 +4,7 @@ using WireMock.Handlers; using WireMock.Logging; using WireMock.Matchers; using WireMock.Util; +using JetBrains.Annotations; #if !USE_ASPNETCORE using Owin; #else @@ -64,5 +65,7 @@ namespace WireMock.Owin string X509CertificatePassword { get; set; } bool CustomCertificateDefined { get; } + + bool? SaveUnmatchedRequests { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs b/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs index 79a485dc..0b62aa86 100644 --- a/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs +++ b/src/WireMock.Net/Owin/Mappers/OwinRequestMapper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -23,7 +23,7 @@ namespace WireMock.Owin.Mappers /// public async Task MapAsync(IRequest request, IWireMockMiddlewareOptions options) { - (UrlDetails urldetails, string clientIP) = ParseRequest(request); + var (urlDetails, clientIP) = ParseRequest(request); string method = request.Method; @@ -68,7 +68,7 @@ namespace WireMock.Owin.Mappers body = await BodyParser.Parse(bodyParserSettings); } - return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow }; + return new RequestMessage(urlDetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow }; } private (UrlDetails UrlDetails, string ClientIP) ParseRequest(IRequest request) diff --git a/src/WireMock.Net/Owin/WireMockMiddleware.cs b/src/WireMock.Net/Owin/WireMockMiddleware.cs index 8e70eda9..b70fb468 100644 --- a/src/WireMock.Net/Owin/WireMockMiddleware.cs +++ b/src/WireMock.Net/Owin/WireMockMiddleware.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using WireMock.Logging; using System.Linq; +using HandlebarsDotNet.Helpers.Utils; using WireMock.Matchers; using WireMock.Http; using WireMock.Owin.Mappers; @@ -35,28 +36,18 @@ namespace WireMock.Owin #if !USE_ASPNETCORE public WireMockMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinRequestMapper requestMapper, IOwinResponseMapper responseMapper, IMappingMatcher mappingMatcher) : base(next) { - Check.NotNull(options, nameof(options)); - Check.NotNull(requestMapper, nameof(requestMapper)); - Check.NotNull(responseMapper, nameof(responseMapper)); - Check.NotNull(mappingMatcher, nameof(mappingMatcher)); - - _options = options; - _requestMapper = requestMapper; - _responseMapper = responseMapper; - _mappingMatcher = mappingMatcher; + _options = Check.NotNull(options, nameof(options)); + _requestMapper = Check.NotNull(requestMapper, nameof(requestMapper)); + _responseMapper = Check.NotNull(responseMapper, nameof(responseMapper)); + _mappingMatcher = Check.NotNull(mappingMatcher, nameof(mappingMatcher)); } #else public WireMockMiddleware(Next next, IWireMockMiddlewareOptions options, IOwinRequestMapper requestMapper, IOwinResponseMapper responseMapper, IMappingMatcher mappingMatcher) { - Check.NotNull(options, nameof(options)); - Check.NotNull(requestMapper, nameof(requestMapper)); - Check.NotNull(responseMapper, nameof(responseMapper)); - Check.NotNull(mappingMatcher, nameof(mappingMatcher)); - - _options = options; - _requestMapper = requestMapper; - _responseMapper = responseMapper; - _mappingMatcher = mappingMatcher; + _options = Check.NotNull(options, nameof(options)); + _requestMapper = Check.NotNull(requestMapper, nameof(requestMapper)); + _responseMapper = Check.NotNull(responseMapper, nameof(responseMapper)); + _mappingMatcher = Check.NotNull(mappingMatcher, nameof(mappingMatcher)); } #endif @@ -70,20 +61,18 @@ namespace WireMock.Owin { lock (_lock) { - return InvokeInternal(ctx); + return InvokeInternalAsync(ctx); } } - else - { - return InvokeInternal(ctx); - } + + return InvokeInternalAsync(ctx); } - private async Task InvokeInternal(IContext ctx) + private async Task InvokeInternalAsync(IContext ctx) { var request = await _requestMapper.MapAsync(ctx.Request, _options); - bool logRequest = false; + var logRequest = false; ResponseMessage response = null; (MappingMatcherResult Match, MappingMatcherResult Partial) result = (null, null); try @@ -185,6 +174,19 @@ namespace WireMock.Owin LogRequest(log, logRequest); + try + { + if (_options.SaveUnmatchedRequests == true && result.Match?.RequestMatchResult.IsPerfectMatch != true) + { + var filename = $"{log.Guid}.LogEntry.json"; + _options.FileSystemHandler?.WriteUnmatchedRequest(filename, Util.JsonUtils.Serialize(log)); + } + } + catch + { + // Empty catch + } + await _responseMapper.MapAsync(response, ctx.Response); } diff --git a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs index 6e491d7b..292175d2 100644 --- a/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs +++ b/src/WireMock.Net/Owin/WireMockMiddlewareOptions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using WireMock.Handlers; using WireMock.Logging; @@ -78,5 +78,8 @@ namespace WireMock.Owin public bool CustomCertificateDefined => !string.IsNullOrEmpty(X509StoreName) && !string.IsNullOrEmpty(X509StoreLocation) || !string.IsNullOrEmpty(X509CertificateFilePath) && !string.IsNullOrEmpty(X509CertificatePassword); + + /// + public bool? SaveUnmatchedRequests { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Serialization/JsonSerializationConstants.cs b/src/WireMock.Net/Serialization/JsonSerializationConstants.cs index b251a340..5e02fb3e 100644 --- a/src/WireMock.Net/Serialization/JsonSerializationConstants.cs +++ b/src/WireMock.Net/Serialization/JsonSerializationConstants.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; namespace WireMock.Serialization { @@ -15,5 +15,10 @@ namespace WireMock.Serialization Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Include }; + + public static readonly JsonSerializerSettings JsonDeserializerSettingsWithDateParsingNone = new JsonSerializerSettings + { + DateParseHandling = DateParseHandling.None + }; } } \ No newline at end of file diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs index ed306bb7..0c663ce0 100644 --- a/src/WireMock.Net/Server/WireMockServer.Admin.cs +++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs @@ -291,7 +291,9 @@ namespace WireMock.Server GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds, AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods, HandleRequestsSynchronously = _settings.HandleRequestsSynchronously, - ThrowExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails + ThrowExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails, + UseRegexExtended = _settings.UseRegexExtended, + SaveUnmatchedRequests = _settings.SaveUnmatchedRequests }; return ToJson(model); @@ -302,31 +304,16 @@ namespace WireMock.Server var settings = DeserializeObject(requestMessage); _options.MaxRequestLogCount = settings.MaxRequestLogCount; _options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration; - - if (settings.AllowPartialMapping != null) - { - _options.AllowPartialMapping = settings.AllowPartialMapping.Value; - } - + _options.AllowPartialMapping = settings.AllowPartialMapping; if (settings.GlobalProcessingDelay != null) { _options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value); } - - if (settings.AllowBodyForAllHttpMethods != null) - { - _options.AllowBodyForAllHttpMethods = settings.AllowBodyForAllHttpMethods.Value; - } - - if (settings.HandleRequestsSynchronously != null) - { - _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously.Value; - } - - if (settings.ThrowExceptionWhenMatcherFails != null) - { - _settings.ThrowExceptionWhenMatcherFails = settings.ThrowExceptionWhenMatcherFails.Value; - } + _options.AllowBodyForAllHttpMethods = settings.AllowBodyForAllHttpMethods; + _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously; + _settings.ThrowExceptionWhenMatcherFails = settings.ThrowExceptionWhenMatcherFails; + _settings.UseRegexExtended = settings.UseRegexExtended; + _settings.SaveUnmatchedRequests = settings.SaveUnmatchedRequests; return ResponseMessageBuilder.Create("Settings updated"); } diff --git a/src/WireMock.Net/Server/WireMockServer.cs b/src/WireMock.Net/Server/WireMockServer.cs index 5146f3e1..c3ad3dcf 100644 --- a/src/WireMock.Net/Server/WireMockServer.cs +++ b/src/WireMock.Net/Server/WireMockServer.cs @@ -226,6 +226,7 @@ namespace WireMock.Server _options.Logger = _settings.Logger; _options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing; _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously; + _options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests; if (settings.CustomCertificateDefined) { diff --git a/src/WireMock.Net/Settings/IWireMockServerSettings.cs b/src/WireMock.Net/Settings/IWireMockServerSettings.cs index b5a93ea3..610496e3 100644 --- a/src/WireMock.Net/Settings/IWireMockServerSettings.cs +++ b/src/WireMock.Net/Settings/IWireMockServerSettings.cs @@ -213,15 +213,21 @@ namespace WireMock.Settings bool CustomCertificateDefined { get; } /// - /// Defines the global IWebhookSettingsto use + /// Defines the global IWebhookSettings to use. /// [PublicAPI] IWebhookSettings WebhookSettings { get; set; } /// - /// Use the instead of the default . + /// Use the instead of the default (default set to true). /// [PublicAPI] - bool? UseRegexExtended { get; } + bool? UseRegexExtended { get; set; } + + /// + /// Save unmatched requests to a file using the (default set to false). + /// + [PublicAPI] + bool? SaveUnmatchedRequests { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Settings/WireMockServerSettings.cs b/src/WireMock.Net/Settings/WireMockServerSettings.cs index eb345bc4..ab55eb30 100644 --- a/src/WireMock.Net/Settings/WireMockServerSettings.cs +++ b/src/WireMock.Net/Settings/WireMockServerSettings.cs @@ -20,7 +20,6 @@ namespace WireMock.Settings public int? Port { get; set; } /// - // ReSharper disable once InconsistentNaming [PublicAPI] public bool? UseSSL { get; set; } @@ -155,5 +154,9 @@ namespace WireMock.Settings /// [PublicAPI] public bool? UseRegexExtended { get; set; } = true; + + /// + [PublicAPI] + public bool? SaveUnmatchedRequests { get; set; } } } \ No newline at end of file diff --git a/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs b/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs index 7a517f14..101c80a0 100644 --- a/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs +++ b/src/WireMock.Net/Settings/WireMockServerSettingsParser.cs @@ -49,7 +49,8 @@ namespace WireMock.Settings DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing"), HandleRequestsSynchronously = parser.GetBoolValue("HandleRequestsSynchronously"), ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails"), - UseRegexExtended = parser.GetBoolValue(nameof(IWireMockServerSettings.UseRegexExtended), true) + UseRegexExtended = parser.GetBoolValue(nameof(IWireMockServerSettings.UseRegexExtended), true), + SaveUnmatchedRequests = parser.GetBoolValue(nameof(IWireMockServerSettings.SaveUnmatchedRequests)) }; if (logger != null) diff --git a/src/WireMock.Net/Util/JsonUtils.cs b/src/WireMock.Net/Util/JsonUtils.cs index d3ef7f3b..19626932 100644 --- a/src/WireMock.Net/Util/JsonUtils.cs +++ b/src/WireMock.Net/Util/JsonUtils.cs @@ -1,18 +1,19 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using WireMock.Serialization; namespace WireMock.Util { internal static class JsonUtils { - private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings + public static string Serialize(T value) { - DateParseHandling = DateParseHandling.None - }; + return JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsIncludeNullValues); + } /// /// Load a Newtonsoft.Json.Linq.JObject from a string that contains JSON. @@ -22,7 +23,7 @@ namespace WireMock.Util /// A Newtonsoft.Json.Linq.JToken populated from the string that contains JSON. public static JToken Parse(string json) { - return JsonConvert.DeserializeObject(json, JsonSerializerSettings); + return JsonConvert.DeserializeObject(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone); } /// @@ -33,7 +34,7 @@ namespace WireMock.Util /// The deserialized object from the JSON string. public static object DeserializeObject(string json) { - return JsonConvert.DeserializeObject(json, JsonSerializerSettings); + return JsonConvert.DeserializeObject(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone); } /// @@ -44,7 +45,7 @@ namespace WireMock.Util /// The deserialized object from the JSON string. public static T DeserializeObject(string json) { - return JsonConvert.DeserializeObject(json, JsonSerializerSettings); + return JsonConvert.DeserializeObject(json, JsonSerializationConstants.JsonDeserializerSettingsWithDateParsingNone); } public static T ParseJTokenToObject(object value) diff --git a/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs b/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs index 3da66fe2..30a7b5c2 100644 --- a/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs +++ b/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs @@ -85,5 +85,22 @@ namespace WireMock.Net.Tests.Handlers // Act Check.ThatCode(() => _sut.DeleteFile(null)).Throws(); } + + [Fact] + public void LocalFileSystemHandler_GetUnmatchedRequestsFolder() + { + // Act + string result = _sut.GetUnmatchedRequestsFolder(); + + // Assert + Check.That(result).EndsWith(Path.Combine("requests", "unmatched")); + } + + [Fact] + public void LocalFileSystemHandler_WriteUnmatchedRequest() + { + // Act + Check.ThatCode(() => _sut.WriteUnmatchedRequest(null, null)).Throws(); + } } } \ No newline at end of file