Compare commits

..

2 Commits

Author SHA1 Message Date
Stef Heyenrath
c96d7d31b1 1.5.44 2023-12-14 21:08:05 +01:00
Mindaugas Laganeckas
7b8e7bb684 Implement prefix for saved mapping file (#1040)
* Implement PrefixForSavedMappingFile

* Add missing new line

* Add missing new line

* Fix warning

* Fix typo

* Change from readonly to const

* Assign default value

* Use nameof()

* Change from readonly to const

* Update tests

* Update failing test

* Rename settingsMock to settings

* Create public const

* Use const from ProxyAndRecordSettings

---------

Co-authored-by: Mindaugas Laganeckas <mindaugas.laganeckas@nexigroup.com>
2023-12-14 08:28:21 +01:00
11 changed files with 240 additions and 29 deletions

View File

@@ -1,3 +1,8 @@
# 1.5.44 (14 December 2023)
- [#1040](https://github.com/WireMock-Net/WireMock.Net/pull/1040) - Implement prefix for saved mapping file [feature] contributed by [MindaugasLaganeckas](https://github.com/MindaugasLaganeckas)
- [#1033](https://github.com/WireMock-Net/WireMock.Net/issues/1033) - How to get a Random Long? [bug]
- [#1037](https://github.com/WireMock-Net/WireMock.Net/issues/1037) - Make mapping filenames more user friendly [feature]
# 1.5.43 (11 December 2023)
- [#1026](https://github.com/WireMock-Net/WireMock.Net/pull/1026) - Add ProxyUrlReplaceSettings to Response [feature] contributed by [StefH](https://github.com/StefH)
- [#1038](https://github.com/WireMock-Net/WireMock.Net/pull/1038) - Proxy all requests - even a repeated one [feature] contributed by [sameena-ops](https://github.com/sameena-ops)

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.5.43</VersionPrefix>
<VersionPrefix>1.5.44</VersionPrefix>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>

View File

@@ -1,6 +1,6 @@
rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.5.43
SET version=1.5.44
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%

View File

@@ -1,7 +1,6 @@
# 1.5.43 (11 December 2023)
- #1026 Add ProxyUrlReplaceSettings to Response [feature]
- #1038 Proxy all requests - even a repeated one [feature]
- #592 Proxy all requests - even a repeated one [feature]
- #1024 Scenario with proxy not removing route prefix [feature]
# 1.5.44 (14 December 2023)
- #1040 Implement prefix for saved mapping file [feature]
- #1033 How to get a Random Long? [bug]
- #1037 Make mapping filenames more user friendly [feature]
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -69,6 +69,11 @@ public class ProxyAndRecordSettingsModel
/// </summary>
public bool AppendGuidToSavedMappingFile { get; set; }
/// <summary>
/// Set prefix for saved mapping file.
/// </summary>
public string PrefixForSavedMappingFile { get; set; }
/// <summary>
/// Defines the Replace Settings.
/// </summary>

View File

@@ -0,0 +1,48 @@
using System.IO;
using System.Linq;
using Stef.Validation;
using WireMock.Settings;
namespace WireMock.Serialization;
/// <summary>
/// Creates sanitized file names for mappings
/// </summary>
public class MappingFileNameSanitizer
{
private const char ReplaceChar = '_';
private readonly WireMockServerSettings _settings;
public MappingFileNameSanitizer(WireMockServerSettings settings)
{
_settings = Guard.NotNull(settings);
}
/// <summary>
/// Creates sanitized file names for mappings
/// </summary>
public string BuildSanitizedFileName(IMapping mapping)
{
string name;
if (!string.IsNullOrEmpty(mapping.Title))
{
// remove 'Proxy Mapping for ' and an extra space character after the HTTP request method
name = mapping.Title.Replace(ProxyAndRecordSettings.DefaultPrefixForSavedMappingFile, "").Replace(' '.ToString(), string.Empty);
if (_settings.ProxyAndRecordSettings?.AppendGuidToSavedMappingFile == true)
{
name += $"{ReplaceChar}{mapping.Guid}";
}
}
else
{
name = mapping.Guid.ToString();
}
if (!string.IsNullOrEmpty(_settings.ProxyAndRecordSettings?.PrefixForSavedMappingFile))
{
name = $"{_settings.ProxyAndRecordSettings.PrefixForSavedMappingFile}{ReplaceChar}{name}";
}
return $"{Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, ReplaceChar))}.json";
}
}

View File

@@ -10,11 +10,13 @@ internal class MappingToFileSaver
{
private readonly WireMockServerSettings _settings;
private readonly MappingConverter _mappingConverter;
private readonly MappingFileNameSanitizer _fileNameSanitizer;
public MappingToFileSaver(WireMockServerSettings settings, MappingConverter mappingConverter)
{
_settings = Guard.NotNull(settings);
_mappingConverter = Guard.NotNull(mappingConverter);
_fileNameSanitizer = new MappingFileNameSanitizer(settings);
}
public void SaveMappingsToFile(IMapping[] mappings, string? folder = null)
@@ -42,7 +44,7 @@ internal class MappingToFileSaver
var model = _mappingConverter.ToMappingModel(mapping);
var filename = BuildSanitizedFileName(mapping);
var filename = _fileNameSanitizer.BuildSanitizedFileName(mapping);
var path = Path.Combine(folder, filename);
Save(model, path);
@@ -54,23 +56,4 @@ internal class MappingToFileSaver
_settings.FileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(value, JsonSerializationConstants.JsonSerializerSettingsDefault));
}
private string BuildSanitizedFileName(IMapping mapping, char replaceChar = '_')
{
string name;
if (!string.IsNullOrEmpty(mapping.Title))
{
name = mapping.Title!;
if (_settings.ProxyAndRecordSettings?.AppendGuidToSavedMappingFile == true)
{
name += $"{replaceChar}{mapping.Guid}";
}
}
else
{
name = mapping.Guid.ToString();
}
return $"{Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar))}.json";
}
}

View File

@@ -7,6 +7,11 @@ namespace WireMock.Settings;
/// </summary>
public class ProxyAndRecordSettings : HttpClientSettings
{
/// <summary>
/// Default prefix value for saved mapping file
/// </summary>
public const string DefaultPrefixForSavedMappingFile = "Proxy Mapping for ";
/// <summary>
/// The URL to proxy.
/// </summary>
@@ -95,9 +100,14 @@ public class ProxyAndRecordSettings : HttpClientSettings
/// </summary>
public bool AppendGuidToSavedMappingFile { get; set; }
/// <summary>
/// Set prefix for saved mapping file.
/// </summary>
public string PrefixForSavedMappingFile { get; set; } = DefaultPrefixForSavedMappingFile;
/// <summary>
/// Proxy all Api calls, irrespective of any condition
/// </summary>
[PublicAPI]
public bool ProxyAll { get; set; } = false;
}
}

View File

@@ -120,6 +120,7 @@ public static class WireMockServerSettingsParser
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
UseDefinedRequestMatchers = parser.GetBoolValue(nameof(ProxyAndRecordSettings.UseDefinedRequestMatchers)),
AppendGuidToSavedMappingFile = parser.GetBoolValue(nameof(ProxyAndRecordSettings.AppendGuidToSavedMappingFile)),
PrefixForSavedMappingFile = parser.GetStringValue(nameof(ProxyAndRecordSettings.PrefixForSavedMappingFile), null),
Url = proxyUrl!,
SaveMappingSettings = new ProxySaveMappingSettings
{

View File

@@ -0,0 +1,160 @@
using System;
using Moq;
using WireMock.Serialization;
using WireMock.Settings;
using Xunit;
namespace WireMock.Net.Tests.Serialization;
public class MappingFileNameSanitizerTests
{
private const string MappingGuid = "ce216a13-e7d6-42d7-91ac-8ae709e2add1";
private const string MappingTitle = "Proxy Mapping for POST _ordermanagement_v1_orders_cancel";
[Fact]
public void BuildSanitizedFileName_WithTitleAndGuid_AppendsGuid()
{
// Arrange
var mappingMock = new Mock<IMapping>();
mappingMock.Setup(m => m.Title).Returns(MappingTitle);
mappingMock.Setup(m => m.Guid).Returns(new Guid(MappingGuid));
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
AppendGuidToSavedMappingFile = true
}
};
var sanitizer = new MappingFileNameSanitizer(settings);
// Act
var result = sanitizer.BuildSanitizedFileName(mappingMock.Object);
// Assert
Assert.Equal($"Proxy Mapping for _POST_ordermanagement_v1_orders_cancel_{MappingGuid}.json", result);
}
[Fact]
public void BuildSanitizedFileName_WithoutTitle_UsesGuid()
{
// Arrange
var mappingMock = new Mock<IMapping>();
mappingMock.Setup(m => m.Title).Returns((string?)null);
mappingMock.Setup(m => m.Guid).Returns(new Guid(MappingGuid));
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ()
};
var sanitizer = new MappingFileNameSanitizer(settings);
// Act
var result = sanitizer.BuildSanitizedFileName(mappingMock.Object);
// Assert
Assert.Equal($"Proxy Mapping for _{MappingGuid}.json", result);
}
[Fact]
public void BuildSanitizedFileName_WithTitleAndGuid_NoAppendGuidSetting()
{
// Arrange
var mappingMock = new Mock<IMapping>();
mappingMock.Setup(m => m.Title).Returns(MappingTitle);
mappingMock.Setup(m => m.Guid).Returns(new Guid(MappingGuid));
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
AppendGuidToSavedMappingFile = false
}
};
var sanitizer = new MappingFileNameSanitizer(settings);
// Act
var result = sanitizer.BuildSanitizedFileName(mappingMock.Object);
// Assert
Assert.Equal("Proxy Mapping for _POST_ordermanagement_v1_orders_cancel.json", result);
}
[Fact]
public void BuildSanitizedFileName_WithPrefix_AddsPrefix()
{
// Arrange
var mappingMock = new Mock<IMapping>();
mappingMock.Setup(m => m.Title).Returns(MappingTitle);
mappingMock.Setup(m => m.Guid).Returns(new Guid(MappingGuid));
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
PrefixForSavedMappingFile = "Prefix"
}
};
var sanitizer = new MappingFileNameSanitizer(settings);
// Act
var result = sanitizer.BuildSanitizedFileName(mappingMock.Object);
// Assert
Assert.Equal($"Prefix_POST_ordermanagement_v1_orders_cancel.json", result);
}
[Fact]
public void BuildSanitizedFileName_WithPrefix_AddsPrefixEmptyString()
{
// Arrange
var mappingMock = new Mock<IMapping>();
mappingMock.Setup(m => m.Title).Returns(MappingTitle);
mappingMock.Setup(m => m.Guid).Returns(new Guid(MappingGuid));
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
PrefixForSavedMappingFile = string.Empty
}
};
var sanitizer = new MappingFileNameSanitizer(settings);
// Act
var result = sanitizer.BuildSanitizedFileName(mappingMock.Object);
// Assert
Assert.Equal($"POST_ordermanagement_v1_orders_cancel.json", result);
}
[Fact]
public void BuildSanitizedFileName_WithTitleAndGuid_WithPrefixAndAppendGuidSetting()
{
// Arrange
var mappingMock = new Mock<IMapping>();
mappingMock.Setup(m => m.Title).Returns(MappingTitle);
mappingMock.Setup(m => m.Guid).Returns(new Guid(MappingGuid));
var settings = new WireMockServerSettings
{
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
PrefixForSavedMappingFile = "Prefix",
AppendGuidToSavedMappingFile = true
}
};
var sanitizer = new MappingFileNameSanitizer(settings);
// Act
var result = sanitizer.BuildSanitizedFileName(mappingMock.Object);
// Assert
Assert.Equal($"Prefix_POST_ordermanagement_v1_orders_cancel_{MappingGuid}.json", result);
}
}

View File

@@ -174,7 +174,7 @@ public class WireMockServerProxyTests
server.Mappings.Should().HaveCount(2);
// Verify
fileSystemHandlerMock.Verify(f => f.WriteMappingFile($"m{System.IO.Path.DirectorySeparatorChar}{title}.json", It.IsRegex(stringBody)), Times.Once);
fileSystemHandlerMock.Verify(f => f.WriteMappingFile($"m{System.IO.Path.DirectorySeparatorChar}Proxy Mapping for _{title}.json", It.IsRegex(stringBody)), Times.Once);
}
[Fact]