From 97a749d54a69e73056a51bd3c31d3c39a5c925a5 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Sat, 17 Feb 2024 13:32:28 +0100 Subject: [PATCH] Fix some SonarCloud issues (#1058) * Fix some SonarCloud issues * added some xml comments --- .../WireMockANumberOfCallsAssertions.cs | 40 ++-- .../Assertions/WireMockReceivedAssertions.cs | 81 ++++--- .../IWireMockOpenApiParserExampleValues.cs | 18 +- ...reMockOpenApiParserDynamicExampleValues.cs | 18 +- .../WireMockOpenApiParserExampleValues.cs | 18 +- src/WireMock.Net/Owin/AspNetCoreSelfHost.cs | 205 +++++++++--------- .../RequestBuilders/Request.ClientIP.cs | 10 +- .../Server/WireMockServer.Admin.cs | 10 +- .../Server/WireMockServer.AdminFiles.cs | 203 ++++++++--------- .../Server/WireMockServer.LogEntries.cs | 2 +- .../Settings/ProxySaveMappingSetting.cs | 38 +++- src/WireMock.Net/Util/CSharpFormatter.cs | 7 +- 12 files changed, 348 insertions(+), 302 deletions(-) diff --git a/src/WireMock.Net.FluentAssertions/Assertions/WireMockANumberOfCallsAssertions.cs b/src/WireMock.Net.FluentAssertions/Assertions/WireMockANumberOfCallsAssertions.cs index d0a50813..da103150 100644 --- a/src/WireMock.Net.FluentAssertions/Assertions/WireMockANumberOfCallsAssertions.cs +++ b/src/WireMock.Net.FluentAssertions/Assertions/WireMockANumberOfCallsAssertions.cs @@ -2,22 +2,34 @@ using Stef.Validation; using WireMock.Server; // ReSharper disable once CheckNamespace -namespace WireMock.FluentAssertions +namespace WireMock.FluentAssertions; + +/// +/// Provides assertion methods to verify the number of calls made to a WireMock server. +/// This class is used in the context of FluentAssertions. +/// +public class WireMockANumberOfCallsAssertions { - public class WireMockANumberOfCallsAssertions + private readonly IWireMockServer _server; + private readonly int _callsCount; + + /// + /// Initializes a new instance of the class. + /// + /// The WireMock server to assert against. + /// The expected number of calls to assert. + public WireMockANumberOfCallsAssertions(IWireMockServer server, int callsCount) { - private readonly IWireMockServer _server; - private readonly int _callsCount; + _server = Guard.NotNull(server); + _callsCount = callsCount; + } - public WireMockANumberOfCallsAssertions(IWireMockServer server, int callsCount) - { - _server = Guard.NotNull(server); - _callsCount = callsCount; - } - - public WireMockAssertions Calls() - { - return new WireMockAssertions(_server, _callsCount); - } + /// + /// Returns an instance of which can be used to assert the expected number of calls. + /// + /// A instance for asserting the number of calls to the server. + public WireMockAssertions Calls() + { + return new WireMockAssertions(_server, _callsCount); } } \ No newline at end of file diff --git a/src/WireMock.Net.FluentAssertions/Assertions/WireMockReceivedAssertions.cs b/src/WireMock.Net.FluentAssertions/Assertions/WireMockReceivedAssertions.cs index 74d68c89..a9c19a40 100644 --- a/src/WireMock.Net.FluentAssertions/Assertions/WireMockReceivedAssertions.cs +++ b/src/WireMock.Net.FluentAssertions/Assertions/WireMockReceivedAssertions.cs @@ -2,50 +2,49 @@ using FluentAssertions.Primitives; using WireMock.Server; // ReSharper disable once CheckNamespace -namespace WireMock.FluentAssertions +namespace WireMock.FluentAssertions; + +/// +/// Contains a number of methods to assert that the is in the expected state. +/// +public class WireMockReceivedAssertions : ReferenceTypeAssertions { /// - /// Contains a number of methods to assert that the is in the expected state. + /// Create a WireMockReceivedAssertions. /// - public class WireMockReceivedAssertions : ReferenceTypeAssertions + /// The . + public WireMockReceivedAssertions(IWireMockServer server) : base(server) { - /// - /// Create a WireMockReceivedAssertions. - /// - /// The . - public WireMockReceivedAssertions(IWireMockServer server) : base(server) - { - } - - /// - /// Asserts if has received no calls. - /// - /// - public WireMockAssertions HaveReceivedNoCalls() - { - return new WireMockAssertions(Subject, 0); - } - - /// - /// Asserts if has received a call. - /// - /// - public WireMockAssertions HaveReceivedACall() - { - return new WireMockAssertions(Subject, null); - } - - /// - /// Asserts if has received n-calls. - /// - /// - /// - public WireMockANumberOfCallsAssertions HaveReceived(int callsCount) - { - return new WireMockANumberOfCallsAssertions(Subject, callsCount); - } - - /// - protected override string Identifier => "wiremockserver"; } + + /// + /// Asserts if has received no calls. + /// + /// + public WireMockAssertions HaveReceivedNoCalls() + { + return new WireMockAssertions(Subject, 0); + } + + /// + /// Asserts if has received a call. + /// + /// + public WireMockAssertions HaveReceivedACall() + { + return new WireMockAssertions(Subject, null); + } + + /// + /// Asserts if has received n-calls. + /// + /// + /// + public WireMockANumberOfCallsAssertions HaveReceived(int callsCount) + { + return new WireMockANumberOfCallsAssertions(Subject, callsCount); + } + + /// + protected override string Identifier => "wiremockserver"; } \ No newline at end of file diff --git a/src/WireMock.Net.OpenApiParser/Settings/IWireMockOpenApiParserExampleValues.cs b/src/WireMock.Net.OpenApiParser/Settings/IWireMockOpenApiParserExampleValues.cs index be65c13f..a9f395e1 100644 --- a/src/WireMock.Net.OpenApiParser/Settings/IWireMockOpenApiParserExampleValues.cs +++ b/src/WireMock.Net.OpenApiParser/Settings/IWireMockOpenApiParserExampleValues.cs @@ -11,47 +11,47 @@ public interface IWireMockOpenApiParserExampleValues /// /// An example value for a Boolean. /// - bool Boolean { get; set; } + bool Boolean { get; } /// /// An example value for an Integer. /// - int Integer { get; set; } + int Integer { get; } /// /// An example value for a Float. /// - float Float { get; set; } + float Float { get; } /// /// An example value for a Double. /// - double Double { get; set; } + double Double { get; } /// /// An example value for a Date. /// - Func Date { get; set; } + Func Date { get; } /// /// An example value for a DateTime. /// - Func DateTime { get; set; } + Func DateTime { get; } /// /// An example value for Bytes. /// - byte[] Bytes { get; set; } + byte[] Bytes { get; } /// /// An example value for a Object. /// - object Object { get; set; } + object Object { get; } /// /// An example value for a String. /// - string String { get; set; } + string String { get; } /// /// OpenApi Schema to generate dynamic examples more accurate diff --git a/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserDynamicExampleValues.cs b/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserDynamicExampleValues.cs index 1524fed3..ade2bb50 100644 --- a/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserDynamicExampleValues.cs +++ b/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserDynamicExampleValues.cs @@ -11,31 +11,31 @@ namespace WireMock.Net.OpenApiParser.Settings; public class WireMockOpenApiParserDynamicExampleValues : IWireMockOpenApiParserExampleValues { /// - public virtual bool Boolean { get => RandomizerFactory.GetRandomizer(new FieldOptionsBoolean()).Generate() ?? true; set { } } + public virtual bool Boolean => RandomizerFactory.GetRandomizer(new FieldOptionsBoolean()).Generate() ?? true; /// - public virtual int Integer { get => RandomizerFactory.GetRandomizer(new FieldOptionsInteger()).Generate() ?? 42; set { } } + public virtual int Integer => RandomizerFactory.GetRandomizer(new FieldOptionsInteger()).Generate() ?? 42; /// - public virtual float Float { get => RandomizerFactory.GetRandomizer(new FieldOptionsFloat()).Generate() ?? 4.2f; set { } } + public virtual float Float => RandomizerFactory.GetRandomizer(new FieldOptionsFloat()).Generate() ?? 4.2f; /// - public virtual double Double { get => RandomizerFactory.GetRandomizer(new FieldOptionsDouble()).Generate() ?? 4.2d; set { } } + public virtual double Double => RandomizerFactory.GetRandomizer(new FieldOptionsDouble()).Generate() ?? 4.2d; /// - public virtual Func Date { get { return () => RandomizerFactory.GetRandomizer(new FieldOptionsDateTime()).Generate() ?? System.DateTime.UtcNow.Date; } set { } } + public virtual Func Date { get { return () => RandomizerFactory.GetRandomizer(new FieldOptionsDateTime()).Generate() ?? System.DateTime.UtcNow.Date; } } /// - public virtual Func DateTime { get { return () => RandomizerFactory.GetRandomizer(new FieldOptionsDateTime()).Generate() ?? System.DateTime.UtcNow; } set { } } + public virtual Func DateTime { get { return () => RandomizerFactory.GetRandomizer(new FieldOptionsDateTime()).Generate() ?? System.DateTime.UtcNow; } } /// - public virtual byte[] Bytes { get => RandomizerFactory.GetRandomizer(new FieldOptionsBytes()).Generate(); set { } } + public virtual byte[] Bytes => RandomizerFactory.GetRandomizer(new FieldOptionsBytes()).Generate(); /// - public virtual object Object { get; set; } = "example-object"; + public virtual object Object => "example-object"; /// - public virtual string String { get => RandomizerFactory.GetRandomizer(new FieldOptionsTextRegex { Pattern = @"^[0-9]{2}[A-Z]{5}[0-9]{2}" }).Generate() ?? "example-string"; set { } } + public virtual string String => RandomizerFactory.GetRandomizer(new FieldOptionsTextRegex { Pattern = @"^[0-9]{2}[A-Z]{5}[0-9]{2}" }).Generate() ?? "example-string"; /// public virtual OpenApiSchema? Schema { get; set; } diff --git a/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserExampleValues.cs b/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserExampleValues.cs index 5f550d19..2e1cfb74 100644 --- a/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserExampleValues.cs +++ b/src/WireMock.Net.OpenApiParser/Settings/WireMockOpenApiParserExampleValues.cs @@ -9,31 +9,31 @@ namespace WireMock.Net.OpenApiParser.Settings; public class WireMockOpenApiParserExampleValues : IWireMockOpenApiParserExampleValues { /// - public virtual bool Boolean { get; set; } = true; + public virtual bool Boolean => true; /// - public virtual int Integer { get; set; } = 42; + public virtual int Integer => 42; /// - public virtual float Float { get; set; } = 4.2f; + public virtual float Float => 4.2f; /// - public virtual double Double { get; set; } = 4.2d; + public virtual double Double => 4.2d; /// - public virtual Func Date { get; set; } = () => System.DateTime.UtcNow.Date; + public virtual Func Date { get; } = () => System.DateTime.UtcNow.Date; /// - public virtual Func DateTime { get; set; } = () => System.DateTime.UtcNow; + public virtual Func DateTime { get; } = () => System.DateTime.UtcNow; /// - public virtual byte[] Bytes { get; set; } = { 48, 49, 50 }; + public virtual byte[] Bytes { get; } = { 48, 49, 50 }; /// - public virtual object Object { get; set; } = "example-object"; + public virtual object Object => "example-object"; /// - public virtual string String { get; set; } = "example-string"; + public virtual string String => "example-string"; /// public virtual OpenApiSchema? Schema { get; set; } = new(); diff --git a/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs b/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs index b55643f7..7ffae350 100644 --- a/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs +++ b/src/WireMock.Net/Owin/AspNetCoreSelfHost.cs @@ -14,97 +14,97 @@ using WireMock.Owin.Mappers; using WireMock.Services; using WireMock.Util; -namespace WireMock.Owin +namespace WireMock.Owin; + +internal partial class AspNetCoreSelfHost : IOwinSelfHost { - internal partial class AspNetCoreSelfHost : IOwinSelfHost + private const string CorsPolicyName = "WireMock.Net - Policy"; + + private readonly CancellationTokenSource _cts = new(); + private readonly IWireMockMiddlewareOptions _wireMockMiddlewareOptions; + private readonly IWireMockLogger _logger; + private readonly HostUrlOptions _urlOptions; + + private Exception _runningException; + private IWebHost _host; + + public bool IsStarted { get; private set; } + + public List Urls { get; } = new(); + + public List Ports { get; } = new(); + + public Exception RunningException => _runningException; + + public AspNetCoreSelfHost(IWireMockMiddlewareOptions wireMockMiddlewareOptions, HostUrlOptions urlOptions) { - private const string CorsPolicyName = "WireMock.Net - Policy"; + Guard.NotNull(wireMockMiddlewareOptions); + Guard.NotNull(urlOptions); - private readonly CancellationTokenSource _cts = new CancellationTokenSource(); - private readonly IWireMockMiddlewareOptions _wireMockMiddlewareOptions; - private readonly IWireMockLogger _logger; - private readonly HostUrlOptions _urlOptions; + _logger = wireMockMiddlewareOptions.Logger ?? new WireMockConsoleLogger(); - private Exception _runningException; - private IWebHost _host; + _wireMockMiddlewareOptions = wireMockMiddlewareOptions; + _urlOptions = urlOptions; + } - public bool IsStarted { get; private set; } + public Task StartAsync() + { + var builder = new WebHostBuilder(); - public List Urls { get; } = new(); - - public List Ports { get; } = new(); - - public Exception RunningException => _runningException; - - public AspNetCoreSelfHost(IWireMockMiddlewareOptions wireMockMiddlewareOptions, HostUrlOptions urlOptions) + // Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292 + // On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not + // specified (even though we don't actually use that base path mechanism, since we have our own way of configuring + // a filesystem handler). + if (string.IsNullOrEmpty(AppContext.BaseDirectory)) { - Guard.NotNull(wireMockMiddlewareOptions); - Guard.NotNull(urlOptions); - - _logger = wireMockMiddlewareOptions.Logger ?? new WireMockConsoleLogger(); - - _wireMockMiddlewareOptions = wireMockMiddlewareOptions; - _urlOptions = urlOptions; + builder.UseContentRoot(Directory.GetCurrentDirectory()); } - public Task StartAsync() - { - var builder = new WebHostBuilder(); - - // Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292 - // On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not - // specified (even though we don't actually use that base path mechanism, since we have our own way of configuring - // a filesystem handler). - if (string.IsNullOrEmpty(AppContext.BaseDirectory)) + _host = builder + .UseSetting("suppressStatusMessages", "True") // https://andrewlock.net/suppressing-the-startup-and-shutdown-messages-in-asp-net-core/ + .ConfigureAppConfigurationUsingEnvironmentVariables() + .ConfigureServices(services => { - builder.UseContentRoot(Directory.GetCurrentDirectory()); - } - - _host = builder - .UseSetting("suppressStatusMessages", "True") // https://andrewlock.net/suppressing-the-startup-and-shutdown-messages-in-asp-net-core/ - .ConfigureAppConfigurationUsingEnvironmentVariables() - .ConfigureServices(services => - { - services.AddSingleton(_wireMockMiddlewareOptions); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(_wireMockMiddlewareOptions); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); #if NETCOREAPP3_1 || NET5_0_OR_GREATER - AddCors(services); + AddCors(services); #endif - _wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services); - }) - .Configure(appBuilder => - { - appBuilder.UseMiddleware(); + _wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services); + }) + .Configure(appBuilder => + { + appBuilder.UseMiddleware(); #if NETCOREAPP3_1 || NET5_0_OR_GREATER - UseCors(appBuilder); + UseCors(appBuilder); #endif - _wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder); + _wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder); - appBuilder.UseMiddleware(); + appBuilder.UseMiddleware(); - _wireMockMiddlewareOptions.PostWireMockMiddlewareInit?.Invoke(appBuilder); - }) - .UseKestrel(options => - { - SetKestrelOptionsLimits(options); + _wireMockMiddlewareOptions.PostWireMockMiddlewareInit?.Invoke(appBuilder); + }) + .UseKestrel(options => + { + SetKestrelOptionsLimits(options); - SetHttpsAndUrls(options, _wireMockMiddlewareOptions, _urlOptions.GetDetails()); - }) - .ConfigureKestrelServerOptions() + SetHttpsAndUrls(options, _wireMockMiddlewareOptions, _urlOptions.GetDetails()); + }) + .ConfigureKestrelServerOptions() #if NETSTANDARD1_3 - .UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray()) + .UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray()) #endif - .Build(); + .Build(); - return RunHost(_cts.Token); - } + return RunHost(_cts.Token); + } private Task RunHost(CancellationToken token) { @@ -129,60 +129,59 @@ namespace WireMock.Owin Ports.Add(port); } - IsStarted = true; - }); + IsStarted = true; + }); #if NETSTANDARD1_3 - _logger.Info("Server using netstandard1.3"); + _logger.Info("Server using netstandard1.3"); #elif NETSTANDARD2_0 - _logger.Info("Server using netstandard2.0"); + _logger.Info("Server using netstandard2.0"); #elif NETSTANDARD2_1 - _logger.Info("Server using netstandard2.1"); + _logger.Info("Server using netstandard2.1"); #elif NETCOREAPP3_1 - _logger.Info("Server using .NET Core App 3.1"); + _logger.Info("Server using .NET Core App 3.1"); #elif NET5_0 - _logger.Info("Server using .NET 5.0"); + _logger.Info("Server using .NET 5.0"); #elif NET6_0 - _logger.Info("Server using .NET 6.0"); + _logger.Info("Server using .NET 6.0"); #elif NET7_0 - _logger.Info("Server using .NET 7.0"); + _logger.Info("Server using .NET 7.0"); #elif NET8_0 - _logger.Info("Server using .NET 8.0"); + _logger.Info("Server using .NET 8.0"); #elif NET46 - _logger.Info("Server using .NET Framework 4.6.1 or higher"); + _logger.Info("Server using .NET Framework 4.6.1 or higher"); #endif #if NETSTANDARD1_3 - return Task.Run(() => - { - _host.Run(token); - }); -#else - return _host.RunAsync(token); -#endif - } - catch (Exception e) + return Task.Run(() => { - _runningException = e; - _logger.Error(e.ToString()); - - IsStarted = false; - - return Task.CompletedTask; - } + _host.Run(token); + }); +#else + return _host.RunAsync(token); +#endif } - - public Task StopAsync() + catch (Exception e) { - _cts.Cancel(); + _runningException = e; + _logger.Error(e.ToString()); IsStarted = false; -#if NETSTANDARD1_3 - return Task.FromResult(true); -#else - return _host.StopAsync(); -#endif + + return Task.CompletedTask; } } + + public Task StopAsync() + { + _cts.Cancel(); + + IsStarted = false; +#if NETSTANDARD1_3 + return Task.CompletedTask; +#else + return _host.StopAsync(); +#endif + } } #endif \ No newline at end of file diff --git a/src/WireMock.Net/RequestBuilders/Request.ClientIP.cs b/src/WireMock.Net/RequestBuilders/Request.ClientIP.cs index df9e5471..6b756020 100644 --- a/src/WireMock.Net/RequestBuilders/Request.ClientIP.cs +++ b/src/WireMock.Net/RequestBuilders/Request.ClientIP.cs @@ -23,17 +23,17 @@ public partial class Request } /// - public IRequestBuilder WithClientIP(params string[] paths) + public IRequestBuilder WithClientIP(params string[] clientIPs) { - return WithClientIP(MatchOperator.Or, paths); + return WithClientIP(MatchOperator.Or, clientIPs); } /// - public IRequestBuilder WithClientIP(MatchOperator matchOperator, params string[] paths) + public IRequestBuilder WithClientIP(MatchOperator matchOperator, params string[] clientIPs) { - Guard.NotNullOrEmpty(paths); + Guard.NotNullOrEmpty(clientIPs); - _requestMatchers.Add(new RequestMessageClientIPMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, paths)); + _requestMatchers.Add(new RequestMessageClientIPMatcher(MatchBehaviour.AcceptOnMatch, matchOperator, clientIPs)); return this; } diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs index 72ba9bd1..01b43683 100644 --- a/src/WireMock.Net/Server/WireMockServer.Admin.cs +++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs @@ -111,11 +111,11 @@ public partial class WireMockServer Given(Request.Create().WithPath(AdminScenariosNameWithResetMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenarioReset)); // __admin/files/{filename} - Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePost)); - Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingPut()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePut)); - Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FileGet)); - Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingHead()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FileHead)); - Given(Request.Create().WithPath(_adminFilesFilenamePathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FileDelete)); + Given(Request.Create().WithPath(AdminFilesFilenamePathMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePost)); + Given(Request.Create().WithPath(AdminFilesFilenamePathMatcher).UsingPut()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePut)); + Given(Request.Create().WithPath(AdminFilesFilenamePathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FileGet)); + Given(Request.Create().WithPath(AdminFilesFilenamePathMatcher).UsingHead()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FileHead)); + Given(Request.Create().WithPath(AdminFilesFilenamePathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FileDelete)); // __admin/openapi Given(Request.Create().WithPath($"{AdminOpenApi}/convert").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(OpenApiConvertToMappings)); diff --git a/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs b/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs index 9a085afa..508e5fe9 100644 --- a/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs +++ b/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs @@ -6,111 +6,120 @@ using WireMock.Matchers; using WireMock.Types; using WireMock.Util; -namespace WireMock.Server +namespace WireMock.Server; + +public partial class WireMockServer { - public partial class WireMockServer + private static readonly RegexMatcher AdminFilesFilenamePathMatcher = new(@"^\/__admin\/files\/.*$"); + private static readonly Encoding[] FileBodyIsString = { Encoding.UTF8, Encoding.ASCII }; + + #region Files/{filename} + private IResponseMessage FilePost(IRequestMessage requestMessage) { - private readonly RegexMatcher _adminFilesFilenamePathMatcher = new RegexMatcher(@"^\/__admin\/files\/.*$"); - private static readonly Encoding[] FileBodyIsString = { Encoding.UTF8, Encoding.ASCII }; - - #region Files/{filename} - private IResponseMessage FilePost(IRequestMessage requestMessage) + if (requestMessage.BodyAsBytes is null) { - string filename = GetFileNameFromRequestMessage(requestMessage); - - string mappingFolder = _settings.FileSystemHandler.GetMappingFolder(); - if (!_settings.FileSystemHandler.FolderExists(mappingFolder)) - { - _settings.FileSystemHandler.CreateFolder(mappingFolder); - } - - _settings.FileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes); - - return ResponseMessageBuilder.Create(200, "File created"); + return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "Body is null"); } - private IResponseMessage FilePut(IRequestMessage requestMessage) + var filename = GetFileNameFromRequestMessage(requestMessage); + + var mappingFolder = _settings.FileSystemHandler.GetMappingFolder(); + if (!_settings.FileSystemHandler.FolderExists(mappingFolder)) { - string filename = GetFileNameFromRequestMessage(requestMessage); - - if (!_settings.FileSystemHandler.FileExists(filename)) - { - _settings.Logger.Info("The file '{0}' does not exist, updating file will be skipped.", filename); - return ResponseMessageBuilder.Create(404, "File is not found"); - } - - _settings.FileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes); - - return ResponseMessageBuilder.Create(200, "File updated"); + _settings.FileSystemHandler.CreateFolder(mappingFolder); } - private IResponseMessage FileGet(IRequestMessage requestMessage) - { - string filename = GetFileNameFromRequestMessage(requestMessage); + _settings.FileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes); - if (!_settings.FileSystemHandler.FileExists(filename)) - { - _settings.Logger.Info("The file '{0}' does not exist.", filename); - return ResponseMessageBuilder.Create(404, "File is not found"); - } - - byte[] bytes = _settings.FileSystemHandler.ReadFile(filename); - var response = new ResponseMessage - { - StatusCode = 200, - BodyData = new BodyData - { - BodyAsBytes = bytes, - DetectedBodyType = BodyType.Bytes, - DetectedBodyTypeFromContentType = BodyType.None - } - }; - - if (BytesEncodingUtils.TryGetEncoding(bytes, out var encoding) && FileBodyIsString.Select(x => x.Equals(encoding)).Any()) - { - response.BodyData.DetectedBodyType = BodyType.String; - response.BodyData.BodyAsString = encoding.GetString(bytes); - } - - return response; - } - - /// - /// Checks if file exists. - /// Note: Response is returned with no body as a head request doesn't accept a body, only the status code. - /// - /// The request message. - private IResponseMessage FileHead(IRequestMessage requestMessage) - { - string filename = GetFileNameFromRequestMessage(requestMessage); - - if (!_settings.FileSystemHandler.FileExists(filename)) - { - _settings.Logger.Info("The file '{0}' does not exist.", filename); - return ResponseMessageBuilder.Create(HttpStatusCode.NotFound); - } - - return ResponseMessageBuilder.Create(HttpStatusCode.NoContent); - } - - private IResponseMessage FileDelete(IRequestMessage requestMessage) - { - string filename = GetFileNameFromRequestMessage(requestMessage); - - if (!_settings.FileSystemHandler.FileExists(filename)) - { - _settings.Logger.Info("The file '{0}' does not exist.", filename); - return ResponseMessageBuilder.Create(404, "File is not deleted"); - } - - _settings.FileSystemHandler.DeleteFile(filename); - return ResponseMessageBuilder.Create(200, "File deleted."); - } - - private string GetFileNameFromRequestMessage(IRequestMessage requestMessage) - { - return Path.GetFileName(requestMessage.Path.Substring(AdminFiles.Length + 1)); - } - #endregion + return ResponseMessageBuilder.Create(HttpStatusCode.OK, "File created"); } + + private IResponseMessage FilePut(IRequestMessage requestMessage) + { + if (requestMessage.BodyAsBytes is null) + { + return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "Body is null"); + } + + var filename = GetFileNameFromRequestMessage(requestMessage); + + if (!_settings.FileSystemHandler.FileExists(filename)) + { + _settings.Logger.Info("The file '{0}' does not exist, updating file will be skipped.", filename); + return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "File is not found"); + } + + _settings.FileSystemHandler.WriteFile(filename, requestMessage.BodyAsBytes); + + return ResponseMessageBuilder.Create(HttpStatusCode.OK, "File updated"); + } + + private IResponseMessage FileGet(IRequestMessage requestMessage) + { + var filename = GetFileNameFromRequestMessage(requestMessage); + + if (!_settings.FileSystemHandler.FileExists(filename)) + { + _settings.Logger.Info("The file '{0}' does not exist.", filename); + return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "File is not found"); + } + + var bytes = _settings.FileSystemHandler.ReadFile(filename); + var response = new ResponseMessage + { + StatusCode = 200, + BodyData = new BodyData + { + BodyAsBytes = bytes, + DetectedBodyType = BodyType.Bytes, + DetectedBodyTypeFromContentType = BodyType.None + } + }; + + if (BytesEncodingUtils.TryGetEncoding(bytes, out var encoding) && FileBodyIsString.Select(x => x.Equals(encoding)).Any()) + { + response.BodyData.DetectedBodyType = BodyType.String; + response.BodyData.BodyAsString = encoding.GetString(bytes); + } + + return response; + } + + /// + /// Checks if file exists. + /// Note: Response is returned with no body as a head request doesn't accept a body, only the status code. + /// + /// The request message. + private IResponseMessage FileHead(IRequestMessage requestMessage) + { + var filename = GetFileNameFromRequestMessage(requestMessage); + + if (!_settings.FileSystemHandler.FileExists(filename)) + { + _settings.Logger.Info("The file '{0}' does not exist.", filename); + return ResponseMessageBuilder.Create(HttpStatusCode.NotFound); + } + + return ResponseMessageBuilder.Create(HttpStatusCode.NoContent); + } + + private IResponseMessage FileDelete(IRequestMessage requestMessage) + { + var filename = GetFileNameFromRequestMessage(requestMessage); + + if (!_settings.FileSystemHandler.FileExists(filename)) + { + _settings.Logger.Info("The file '{0}' does not exist.", filename); + return ResponseMessageBuilder.Create(HttpStatusCode.NotFound, "File is not deleted"); + } + + _settings.FileSystemHandler.DeleteFile(filename); + return ResponseMessageBuilder.Create(HttpStatusCode.OK, "File deleted."); + } + + private static string GetFileNameFromRequestMessage(IRequestMessage requestMessage) + { + return Path.GetFileName(requestMessage.Path.Substring(AdminFiles.Length + 1)); + } + #endregion } \ No newline at end of file diff --git a/src/WireMock.Net/Server/WireMockServer.LogEntries.cs b/src/WireMock.Net/Server/WireMockServer.LogEntries.cs index b8b5e02d..29c1c52b 100644 --- a/src/WireMock.Net/Server/WireMockServer.LogEntries.cs +++ b/src/WireMock.Net/Server/WireMockServer.LogEntries.cs @@ -79,7 +79,7 @@ public partial class WireMockServer private NotifyCollectionChangedEventHandler? _logEntriesChanged; - private void LogEntries_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + private void LogEntries_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (_logEntriesChanged is { }) { diff --git a/src/WireMock.Net/Settings/ProxySaveMappingSetting.cs b/src/WireMock.Net/Settings/ProxySaveMappingSetting.cs index ff5fd5f8..ad7a475c 100644 --- a/src/WireMock.Net/Settings/ProxySaveMappingSetting.cs +++ b/src/WireMock.Net/Settings/ProxySaveMappingSetting.cs @@ -1,20 +1,48 @@ +using System; +using Stef.Validation; using WireMock.Matchers; namespace WireMock.Settings; -public class ProxySaveMappingSetting +/// +/// Represents settings for saving a proxy mapping with a non-nullable value and a specific match behaviour. +/// +/// The non-nullable type of the value associated with the proxy save mapping setting. +public class ProxySaveMappingSetting where T : notnull { - public MatchBehaviour MatchBehaviour { get; } = MatchBehaviour.AcceptOnMatch; + /// + /// Gets the match behaviour for the proxy save mapping setting. + /// + /// The match behaviour which determines how matches are evaluated. + public MatchBehaviour MatchBehaviour { get; } + /// + /// Gets the non-nullable value associated with the proxy save mapping setting. + /// + /// The value of type . public T Value { get; } + /// + /// Initializes a new instance of the class with specified non-nullable value and match behaviour. + /// + /// The non-nullable value of type . + /// The match behaviour (optional, default is MatchBehaviour.AcceptOnMatch. + /// Thrown if the is null. public ProxySaveMappingSetting(T value, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch) { - Value = value; + Value = Guard.NotNull(value); MatchBehaviour = matchBehaviour; } + /// + /// Converts a non-nullable value of type to a implicitly. + /// + /// The non-nullable value to convert. public static implicit operator ProxySaveMappingSetting(T value) => new(value); - public static implicit operator T(ProxySaveMappingSetting @this) => @this.Value; -} \ No newline at end of file + /// + /// Converts a to its underlying non-nullable value of type implicitly. + /// + /// The to convert. + public static implicit operator T(ProxySaveMappingSetting instance) => instance.Value; +} diff --git a/src/WireMock.Net/Util/CSharpFormatter.cs b/src/WireMock.Net/Util/CSharpFormatter.cs index a7ac5903..63a17a20 100644 --- a/src/WireMock.Net/Util/CSharpFormatter.cs +++ b/src/WireMock.Net/Util/CSharpFormatter.cs @@ -121,8 +121,7 @@ internal static class CSharpFormatter JTokenType.Boolean => jValue.Value != null ? string.Format(CultureInfo.InvariantCulture, "{0}", jValue.Value).ToLower() : Null, JTokenType.Null => Null, JTokenType.Undefined => Null, - JTokenType.Date when jValue.Value is DateTime dateValue => - $"DateTime.Parse({ToCSharpStringLiteral(dateValue.ToString("s"))})", + JTokenType.Date when jValue.Value is DateTime dateValue => $"DateTime.Parse({ToCSharpStringLiteral(dateValue.ToString("s"))})", _ => $"UNHANDLED_CASE: {jValue.Type}" }, _ => $"UNHANDLED_CASE: {token}" @@ -140,12 +139,12 @@ internal static class CSharpFormatter if (value.Contains('\n')) { - var escapedValue = value?.Replace("\"", "\"\"") ?? string.Empty; + var escapedValue = value.Replace("\"", "\"\""); return $"@\"{escapedValue}\""; } else { - var escapedValue = value?.Replace("\"", "\\\"") ?? string.Empty; + var escapedValue = value.Replace("\"", "\\\""); return $"\"{escapedValue}\""; } }