From 20eb37b0c825d8d5f89a4e7431e45cb310d888b9 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Fri, 6 Jan 2023 19:11:56 +0100 Subject: [PATCH] Add MappingBuilder to build mappings in code and export to Models or JSON (#869) * MappingBuilder * . * ... * sc * t * . --- .../MainApp.cs | 14 ++ src/WireMock.Net/IMappingBuilder.cs | 43 +++++ src/WireMock.Net/MappingBuilder.cs | 116 +++++++++++++ .../Owin/WireMockMiddlewareOptionsHelper.cs | 35 ++++ .../Serialization/MappingToFileSaver.cs | 21 ++- .../Serialization/MatcherMapper.cs | 3 +- .../Server/WireMockServer.Admin.cs | 30 ++-- src/WireMock.Net/Server/WireMockServer.cs | 46 +---- .../Handlers/LocalFileSystemHandlerTests.cs | 163 +++++++++--------- .../WireMock.Net.Tests/MappingBuilderTests.cs | 136 +++++++++++++++ 10 files changed, 465 insertions(+), 142 deletions(-) create mode 100644 src/WireMock.Net/IMappingBuilder.cs create mode 100644 src/WireMock.Net/MappingBuilder.cs create mode 100644 src/WireMock.Net/Owin/WireMockMiddlewareOptionsHelper.cs create mode 100644 test/WireMock.Net.Tests/MappingBuilderTests.cs diff --git a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs index b0d37689..41e82c15 100644 --- a/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs +++ b/examples/WireMock.Net.Console.Net452.Classic/MainApp.cs @@ -37,6 +37,20 @@ namespace WireMock.Net.ConsoleApplication { public static void Run() { + var mappingBuilder = new MappingBuilder(); + mappingBuilder + .Given(Request + .Create() + .WithPath(new WildcardMatcher("/param2", true)) + .WithParam("key", "test") + .UsingGet()) + .RespondWith(Response.Create() + .WithHeader("Content-Type", "application/json") + .WithBodyAsJson(new { result = "param2" })); + + var json = mappingBuilder.ToJson(); + System.Console.WriteLine("mappingBuilder : Json = {0}", json); + var s = WireMockServer.Start(); s.Stop(); diff --git a/src/WireMock.Net/IMappingBuilder.cs b/src/WireMock.Net/IMappingBuilder.cs new file mode 100644 index 00000000..cea40033 --- /dev/null +++ b/src/WireMock.Net/IMappingBuilder.cs @@ -0,0 +1,43 @@ +using WireMock.Admin.Mappings; +using WireMock.Matchers.Request; +using WireMock.Server; + +namespace WireMock; + +/// +/// IMappingBuilder +/// +public interface IMappingBuilder +{ + /// + /// The given. + /// + /// The request matcher. + /// Optional boolean to indicate if this mapping should be saved as static mapping file. + /// The . + IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false); + + /// + /// Gets all the mappings as a list. + /// + /// A list from s. + MappingModel[] GetMappings(); + + /// + /// Convert all mappings to JSON. + /// + /// JSON + string ToJson(); + + /// + /// Save all mappings as a single JSON to a file. + /// + /// The file to write to. + void SaveMappingsToFile(string path); + + /// + /// Save all mappings as multiple JSON files (each file is 1 mapping). + /// + /// The folder to write the files to. + void SaveMappingsToFolder(string folder); +} \ No newline at end of file diff --git a/src/WireMock.Net/MappingBuilder.cs b/src/WireMock.Net/MappingBuilder.cs new file mode 100644 index 00000000..15651f72 --- /dev/null +++ b/src/WireMock.Net/MappingBuilder.cs @@ -0,0 +1,116 @@ +using System; +using System.Linq; +using Newtonsoft.Json; +using Stef.Validation; +using WireMock.Admin.Mappings; +using WireMock.Matchers.Request; +using WireMock.Owin; +using WireMock.Serialization; +using WireMock.Server; +using WireMock.Settings; + +namespace WireMock; + +/// +/// MappingBuilder +/// +public class MappingBuilder : IMappingBuilder +{ + private readonly WireMockServerSettings _settings; + private readonly IWireMockMiddlewareOptions _options; + + private readonly MappingConverter _mappingConverter; + private readonly MappingToFileSaver _mappingToFileSaver; + + /// + /// Create a MappingBuilder + /// + /// The optional . + public MappingBuilder(WireMockServerSettings? settings = null) + { + _settings = settings ?? new WireMockServerSettings(); + _options = WireMockMiddlewareOptionsHelper.InitFromSettings(_settings); + + var matcherMapper = new MatcherMapper(_settings); + _mappingConverter = new MappingConverter(matcherMapper); + _mappingToFileSaver = new MappingToFileSaver(_settings, _mappingConverter); + } + + internal MappingBuilder( + WireMockServerSettings settings, + IWireMockMiddlewareOptions options, + MappingConverter mappingConverter, + MappingToFileSaver mappingToFileSaver + ) + { + _settings = Guard.NotNull(settings); + _options = Guard.NotNull(options); + _mappingConverter = Guard.NotNull(mappingConverter); + _mappingToFileSaver = Guard.NotNull(mappingToFileSaver); + } + + /// + public IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false) + { + return new RespondWithAProvider(RegisterMapping, Guard.NotNull(requestMatcher), _settings, saveToFile); + } + + /// + public MappingModel[] GetMappings() + { + return _options.Mappings.Values.ToArray() + .Where(m => !m.IsAdminInterface) + .Select(_mappingConverter.ToMappingModel) + .ToArray(); + } + + /// + public string ToJson() + { + return ToJson(GetMappings()); + } + + /// + public void SaveMappingsToFile(string path) + { + _mappingToFileSaver.SaveMappingsToFile(GetNonAdminMappings(), path); + } + + /// + public void SaveMappingsToFolder(string? folder) + { + foreach (var mapping in GetNonAdminMappings().Where(m => !m.IsAdminInterface)) + { + _mappingToFileSaver.SaveMappingToFile(mapping, folder); + } + } + + private IMapping[] GetNonAdminMappings() + { + return _options.Mappings.Values.ToArray(); + } + + private void RegisterMapping(IMapping mapping, bool saveToFile) + { + // Check a mapping exists with the same Guid. If so, update the datetime and replace it. + if (_options.Mappings.ContainsKey(mapping.Guid)) + { + mapping.UpdatedAt = DateTime.UtcNow; + _options.Mappings[mapping.Guid] = mapping; + } + else + { + _options.Mappings.TryAdd(mapping.Guid, mapping); + } + + if (saveToFile) + { + _mappingToFileSaver.SaveMappingToFile(mapping); + } + } + + private static string ToJson(object value) + { + return JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsDefault); + } +} \ No newline at end of file diff --git a/src/WireMock.Net/Owin/WireMockMiddlewareOptionsHelper.cs b/src/WireMock.Net/Owin/WireMockMiddlewareOptionsHelper.cs new file mode 100644 index 00000000..8e555a59 --- /dev/null +++ b/src/WireMock.Net/Owin/WireMockMiddlewareOptionsHelper.cs @@ -0,0 +1,35 @@ +using Stef.Validation; +using WireMock.Settings; + +namespace WireMock.Owin; + +internal static class WireMockMiddlewareOptionsHelper +{ + public static IWireMockMiddlewareOptions InitFromSettings(WireMockServerSettings settings, IWireMockMiddlewareOptions? options = null) + { + Guard.NotNull(settings); + + options ??= new WireMockMiddlewareOptions(); + + options.FileSystemHandler = settings.FileSystemHandler; + options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit; + options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit; + options.Logger = settings.Logger; + options.DisableJsonBodyParsing = settings.DisableJsonBodyParsing; + options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously; + options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests; + options.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry; + options.QueryParameterMultipleValueSupport = settings.QueryParameterMultipleValueSupport; + + if (settings.CustomCertificateDefined) + { + options.X509StoreName = settings.CertificateSettings!.X509StoreName; + options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation; + options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName; + options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath; + options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword; + } + + return options; + } +} \ No newline at end of file diff --git a/src/WireMock.Net/Serialization/MappingToFileSaver.cs b/src/WireMock.Net/Serialization/MappingToFileSaver.cs index ce09a909..dcaa2912 100644 --- a/src/WireMock.Net/Serialization/MappingToFileSaver.cs +++ b/src/WireMock.Net/Serialization/MappingToFileSaver.cs @@ -17,6 +17,20 @@ internal class MappingToFileSaver _mappingConverter = Guard.NotNull(mappingConverter); } + public void SaveMappingsToFile(IMapping[] mappings, string? folder = null) + { + folder ??= _settings.FileSystemHandler.GetMappingFolder(); + + if (!_settings.FileSystemHandler.FolderExists(folder)) + { + _settings.FileSystemHandler.CreateFolder(folder); + } + + var models = mappings.Select(_mappingConverter.ToMappingModel).ToArray(); + + Save(models, folder); + } + public void SaveMappingToFile(IMapping mapping, string? folder = null) { folder ??= _settings.FileSystemHandler.GetMappingFolder(); @@ -31,9 +45,14 @@ internal class MappingToFileSaver var filename = BuildSanitizedFileName(mapping); var path = Path.Combine(folder, filename); + Save(model, path); + } + + private void Save(object value, string path) + { _settings.Logger.Info("Saving Mapping file {0}", path); - _settings.FileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, JsonSerializationConstants.JsonSerializerSettingsDefault)); + _settings.FileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsDefault)); } private string BuildSanitizedFileName(IMapping mapping, char replaceChar = '_') diff --git a/src/WireMock.Net/Serialization/MatcherMapper.cs b/src/WireMock.Net/Serialization/MatcherMapper.cs index cc5fdca0..df18842e 100644 --- a/src/WireMock.Net/Serialization/MatcherMapper.cs +++ b/src/WireMock.Net/Serialization/MatcherMapper.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using AnyOfTypes; using SimMetrics.Net; +using Stef.Validation; using WireMock.Admin.Mappings; using WireMock.Extensions; using WireMock.Matchers; @@ -19,7 +20,7 @@ internal class MatcherMapper public MatcherMapper(WireMockServerSettings settings) { - _settings = settings ?? throw new ArgumentNullException(nameof(settings)); + _settings = Guard.NotNull(settings); } public IMatcher[]? Map(IEnumerable? matchers) diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs index f55eef74..2190af56 100644 --- a/src/WireMock.Net/Server/WireMockServer.Admin.cs +++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs @@ -111,10 +111,7 @@ public partial class WireMockServer [PublicAPI] public void SaveStaticMappings(string? folder = null) { - foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface)) - { - _mappingToFileSaver.SaveMappingToFile(mapping, folder); - } + _mappingBuilder.SaveMappingsToFolder(folder); } /// @@ -353,9 +350,9 @@ public partial class WireMockServer return ResponseMessageBuilder.Create("Mappings saved to disk"); } - private IEnumerable ToMappingModels() + private MappingModel[] ToMappingModels() { - return Mappings.Where(m => !m.IsAdminInterface).Select(_mappingConverter.ToMappingModel); + return _mappingBuilder.GetMappings(); } private IResponseMessage MappingsGet(IRequestMessage requestMessage) @@ -418,18 +415,15 @@ public partial class WireMockServer try { var mappingModels = DeserializeRequestMessageToArray(requestMessage); - foreach (var mappingModel in mappingModels) + foreach (var guid in mappingModels.Where(mm => mm.Guid.HasValue).Select(mm => mm.Guid!.Value)) { - if (mappingModel.Guid.HasValue) + if (DeleteMapping(guid)) { - if (DeleteMapping(mappingModel.Guid.Value)) - { - deletedGuids.Add(mappingModel.Guid.Value); - } - else - { - _settings.Logger.Debug($"Did not find/delete mapping with GUID: {mappingModel.Guid.Value}."); - } + deletedGuids.Add(guid); + } + else + { + _settings.Logger.Debug($"Did not find/delete mapping with GUID: {guid}."); } } } @@ -697,7 +691,7 @@ public partial class WireMockServer { return requestMessage.BodyData?.DetectedBodyType switch { - BodyType.String => JsonUtils.DeserializeObject(requestMessage.BodyData.BodyAsString), + BodyType.String => JsonUtils.DeserializeObject(requestMessage.BodyData.BodyAsString!), BodyType.Json when requestMessage.BodyData?.BodyAsJson != null => ((JObject)requestMessage.BodyData.BodyAsJson).ToObject()!, @@ -726,7 +720,7 @@ public partial class WireMockServer { if (value is JArray jArray) { - return jArray.ToObject(); + return jArray.ToObject()!; } var singleResult = ((JObject)value).ToObject(); diff --git a/src/WireMock.Net/Server/WireMockServer.cs b/src/WireMock.Net/Server/WireMockServer.cs index 15ae3e7a..1bb79c98 100644 --- a/src/WireMock.Net/Server/WireMockServer.cs +++ b/src/WireMock.Net/Server/WireMockServer.cs @@ -38,6 +38,7 @@ public partial class WireMockServer : IWireMockServer private readonly MappingConverter _mappingConverter; private readonly MatcherMapper _matcherMapper; private readonly MappingToFileSaver _mappingToFileSaver; + private readonly MappingBuilder _mappingBuilder; /// [PublicAPI] @@ -246,7 +247,7 @@ public partial class WireMockServer : IWireMockServer [PublicAPI] public static WireMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls) { - Guard.NotNullOrEmpty(urls, nameof(urls)); + Guard.NotNullOrEmpty(urls); return new WireMockServer(new WireMockServerSettings { @@ -268,7 +269,7 @@ public partial class WireMockServer : IWireMockServer /// Service start timed out after {TimeSpan.FromMilliseconds(settings.StartTimeout)} protected WireMockServer(WireMockServerSettings settings) { - _settings = settings; + _settings = Guard.NotNull(settings); // Set default values if not provided _settings.Logger = settings.Logger ?? new WireMockNullLogger(); @@ -305,28 +306,12 @@ public partial class WireMockServer : IWireMockServer } } - _options.FileSystemHandler = _settings.FileSystemHandler; - _options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit; - _options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit; - _options.Logger = _settings.Logger; - _options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing; - _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously; - _options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests; - _options.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry; - _options.QueryParameterMultipleValueSupport = settings.QueryParameterMultipleValueSupport; - - if (settings.CustomCertificateDefined) - { - _options.X509StoreName = settings.CertificateSettings!.X509StoreName; - _options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation; - _options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName; - _options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath; - _options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword; - } + WireMockMiddlewareOptionsHelper.InitFromSettings(settings, _options); _matcherMapper = new MatcherMapper(_settings); _mappingConverter = new MappingConverter(_matcherMapper); _mappingToFileSaver = new MappingToFileSaver(_settings, _mappingConverter); + _mappingBuilder = new MappingBuilder(settings, _options, _mappingConverter, _mappingToFileSaver); #if USE_ASPNETCORE _options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration; @@ -538,26 +523,7 @@ public partial class WireMockServer : IWireMockServer [PublicAPI] public IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false) { - return new RespondWithAProvider(RegisterMapping, requestMatcher, _settings, saveToFile); - } - - private void RegisterMapping(IMapping mapping, bool saveToFile) - { - // Check a mapping exists with the same Guid. If so, update the datetime and replace it. - if (_options.Mappings.ContainsKey(mapping.Guid)) - { - mapping.UpdatedAt = DateTime.UtcNow; - _options.Mappings[mapping.Guid] = mapping; - } - else - { - _options.Mappings.TryAdd(mapping.Guid, mapping); - } - - if (saveToFile) - { - _mappingToFileSaver.SaveMappingToFile(mapping); - } + return _mappingBuilder.Given(requestMatcher, saveToFile); } private void InitSettings(WireMockServerSettings settings) diff --git a/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs b/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs index 30a7b5c2..1e9accc8 100644 --- a/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs +++ b/test/WireMock.Net.Tests/Handlers/LocalFileSystemHandlerTests.cs @@ -4,103 +4,102 @@ using NFluent; using WireMock.Handlers; using Xunit; -namespace WireMock.Net.Tests.Handlers +namespace WireMock.Net.Tests.Handlers; + +public class LocalFileSystemHandlerTests { - public class LocalFileSystemHandlerTests + private readonly LocalFileSystemHandler _sut = new(); + + [Fact] + public void LocalFileSystemHandler_GetMappingFolder() { - private readonly LocalFileSystemHandler _sut = new LocalFileSystemHandler(); + // Act + string result = _sut.GetMappingFolder(); - [Fact] - public void LocalFileSystemHandler_GetMappingFolder() - { - // Act - string result = _sut.GetMappingFolder(); + // Assert + Check.That(result).EndsWith(Path.Combine("__admin", "mappings")); + } - // Assert - Check.That(result).EndsWith(Path.Combine("__admin", "mappings")); - } + [Fact] + public void LocalFileSystemHandler_CreateFolder_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.CreateFolder(null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_CreateFolder_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.CreateFolder(null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_WriteMappingFile_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.WriteMappingFile(null, null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_WriteMappingFile_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.WriteMappingFile(null, null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_ReadResponseBodyAsFile_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.ReadResponseBodyAsFile(null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_ReadResponseBodyAsFile_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.ReadResponseBodyAsFile(null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_FileExists_ReturnsFalse() + { + // Act + var result = _sut.FileExists("x.x"); - [Fact] - public void LocalFileSystemHandler_FileExists_ReturnsFalse() - { - // Act - var result = _sut.FileExists("x.x"); + // Assert + Check.That(result).IsFalse(); + } - // Assert - Check.That(result).IsFalse(); - } + [Fact] + public void LocalFileSystemHandler_FileExists_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.FileExists(null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_FileExists_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.FileExists(null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_ReadFile_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.ReadFile(null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_ReadFile_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.ReadFile(null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_ReadFileAsString_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.ReadFileAsString(null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_ReadFileAsString_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.ReadFileAsString(null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_WriteFile_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.WriteFile(null, null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_WriteFile_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.WriteFile(null, null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_DeleteFile_ThrowsArgumentNullException() + { + // Act + Check.ThatCode(() => _sut.DeleteFile(null)).Throws(); + } - [Fact] - public void LocalFileSystemHandler_DeleteFile_ThrowsArgumentNullException() - { - // Act - Check.ThatCode(() => _sut.DeleteFile(null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_GetUnmatchedRequestsFolder() + { + // Act + string result = _sut.GetUnmatchedRequestsFolder(); - [Fact] - public void LocalFileSystemHandler_GetUnmatchedRequestsFolder() - { - // Act - string result = _sut.GetUnmatchedRequestsFolder(); + // Assert + Check.That(result).EndsWith(Path.Combine("requests", "unmatched")); + } - // Assert - Check.That(result).EndsWith(Path.Combine("requests", "unmatched")); - } - - [Fact] - public void LocalFileSystemHandler_WriteUnmatchedRequest() - { - // Act - Check.ThatCode(() => _sut.WriteUnmatchedRequest(null, null)).Throws(); - } + [Fact] + public void LocalFileSystemHandler_WriteUnmatchedRequest() + { + // Act + Check.ThatCode(() => _sut.WriteUnmatchedRequest(null, null)).Throws(); } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/MappingBuilderTests.cs b/test/WireMock.Net.Tests/MappingBuilderTests.cs new file mode 100644 index 00000000..fe9b8697 --- /dev/null +++ b/test/WireMock.Net.Tests/MappingBuilderTests.cs @@ -0,0 +1,136 @@ +using FluentAssertions; +using Moq; +using WireMock.Handlers; +using WireMock.Logging; +using WireMock.Owin; +using WireMock.RequestBuilders; +using WireMock.ResponseBuilders; +using WireMock.Serialization; +using WireMock.Settings; +using Xunit; + +namespace WireMock.Net.Tests; + +public class MappingBuilderTests +{ + private static readonly string MappingGuid = "41372914-1838-4c67-916b-b9aacdd096ce"; + + private readonly Mock _fileSystemHandlerMock; + + private readonly MappingBuilder _sut; + + public MappingBuilderTests() + { + _fileSystemHandlerMock = new Mock(); + + var settings = new WireMockServerSettings + { + FileSystemHandler = _fileSystemHandlerMock.Object, + Logger = Mock.Of() + }; + var options = new WireMockMiddlewareOptions(); + var matcherMapper = new MatcherMapper(settings); + var mappingConverter = new MappingConverter(matcherMapper); + var mappingToFileSaver = new MappingToFileSaver(settings, mappingConverter); + + _sut = new MappingBuilder(settings, options, mappingConverter, mappingToFileSaver); + + _sut.Given(Request.Create() + .WithPath("/foo") + .UsingGet() + ) + .WithGuid(MappingGuid) + .RespondWith(Response.Create() + .WithBody(@"{ msg: ""Hello world!""}") + ); + } + + [Fact] + public void GetMappings() + { + // Act + var mappings = _sut.GetMappings(); + + // Assert + mappings.Should().HaveCount(1); + } + + [Fact] + public void ToJson() + { + // Act + var json = _sut.ToJson(); + + // Assert + json.Should().NotBeEmpty(); + } + + [Fact] + public void SaveMappingsToFile_FolderExists_IsFalse() + { + // Arrange + var path = "path"; + + // Act + _sut.SaveMappingsToFile(path); + + // Verify + _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never); + _fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Once); + _fileSystemHandlerMock.Verify(fs => fs.CreateFolder(path), Times.Once); + _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(path, It.IsAny()), Times.Once); + _fileSystemHandlerMock.VerifyNoOtherCalls(); + } + + [Fact] + public void SaveMappingsToFile_FolderExists_IsTrue() + { + // Arrange + var path = "path"; + _fileSystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny())).Returns(true); + + // Act + _sut.SaveMappingsToFile(path); + + // Verify + _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never); + _fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Once); + _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(path, It.IsAny()), Times.Once); + _fileSystemHandlerMock.VerifyNoOtherCalls(); + } + + [Fact] + public void SaveMappingsToFolder_FolderIsNull() + { + // Arrange + var mappingFolder = "mapping-folder"; + _fileSystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns(mappingFolder); + _fileSystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny())).Returns(true); + + // Act + _sut.SaveMappingsToFolder(null); + + // Verify + _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once); + _fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Once); + _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny(), It.IsAny()), Times.Once); + _fileSystemHandlerMock.VerifyNoOtherCalls(); + } + + [Fact] + public void SaveMappingsToFolder_FolderExists_IsTrue() + { + // Arrange + var path = "path"; + _fileSystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny())).Returns(true); + + // Act + _sut.SaveMappingsToFolder(path); + + // Verify + _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never); + _fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Once); + _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny(), It.IsAny()), Times.Once); + _fileSystemHandlerMock.VerifyNoOtherCalls(); + } +} \ No newline at end of file