diff --git a/src/WireMock.Net.Abstractions/Server/IWireMockServer.cs b/src/WireMock.Net.Abstractions/Server/IWireMockServer.cs index 2ce69fee..013244de 100644 --- a/src/WireMock.Net.Abstractions/Server/IWireMockServer.cs +++ b/src/WireMock.Net.Abstractions/Server/IWireMockServer.cs @@ -5,6 +5,7 @@ using System.Collections.Specialized; using WireMock.Admin.Mappings; using WireMock.Logging; +using WireMock.Matchers.Request; using WireMock.Types; namespace WireMock.Server; @@ -27,12 +28,12 @@ public interface IWireMockServer : IDisposable /// <summary> /// Gets the request logs. /// </summary> - IEnumerable<ILogEntry> LogEntries { get; } + IReadOnlyList<ILogEntry> LogEntries { get; } /// <summary> /// Gets the mappings as MappingModels. /// </summary> - IEnumerable<MappingModel> MappingModels { get; } + IReadOnlyList<MappingModel> MappingModels { get; } // <summary> // Gets the mappings. @@ -109,7 +110,12 @@ public interface IWireMockServer : IDisposable /// <param name="guid">The unique identifier.</param> bool DeleteMapping(Guid guid); - //IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers); + /// <summary> + /// Search log-entries based on matchers. + /// </summary> + /// <param name="matchers">The request matchers to use.</param> + /// <returns>The <see cref="IReadOnlyList{ILogEntry}"/>.</returns> + IReadOnlyList<ILogEntry> FindLogEntries(params IRequestMatcher[] matchers); // IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false); diff --git a/src/WireMock.Net/Matchers/Request/RequestMessageMethodMatcher.cs b/src/WireMock.Net/Matchers/Request/RequestMessageMethodMatcher.cs index 36ff86c5..9835a0fa 100644 --- a/src/WireMock.Net/Matchers/Request/RequestMessageMethodMatcher.cs +++ b/src/WireMock.Net/Matchers/Request/RequestMessageMethodMatcher.cs @@ -26,6 +26,14 @@ internal class RequestMessageMethodMatcher : IRequestMatcher /// </summary> public string[] Methods { get; } + /// <summary> + /// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class. + /// </summary> + /// <param name="methods">The methods.</param> + public RequestMessageMethodMatcher(params string[] methods) : this(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, methods) + { + } + /// <summary> /// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class. /// </summary> diff --git a/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs b/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs index cf8b7ba6..7d2ccb3b 100644 --- a/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs +++ b/src/WireMock.Net/Server/WireMockServer.AdminFiles.cs @@ -11,7 +11,7 @@ namespace WireMock.Server; public partial class WireMockServer { - private static readonly Encoding[] FileBodyIsString = { Encoding.UTF8, Encoding.ASCII }; + private static readonly Encoding[] FileBodyIsString = [Encoding.UTF8, Encoding.ASCII]; #region Files/{filename} private IResponseMessage FilePost(IRequestMessage requestMessage) diff --git a/src/WireMock.Net/Server/WireMockServer.ConvertMapping.cs b/src/WireMock.Net/Server/WireMockServer.ConvertMapping.cs index c3fa6dff..9e3559e0 100644 --- a/src/WireMock.Net/Server/WireMockServer.ConvertMapping.cs +++ b/src/WireMock.Net/Server/WireMockServer.ConvertMapping.cs @@ -308,7 +308,7 @@ private static IResponseBuilder InitResponseBuilder(ResponseModel responseModel) } else if (responseModel.HeadersRaw != null) { - foreach (string headerLine in responseModel.HeadersRaw.Split(new[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries)) + foreach (string headerLine in responseModel.HeadersRaw.Split(["\n", "\r\n"], StringSplitOptions.RemoveEmptyEntries)) { int indexColon = headerLine.IndexOf(":", StringComparison.Ordinal); string key = headerLine.Substring(0, indexColon).TrimStart(' ', '\t'); diff --git a/src/WireMock.Net/Server/WireMockServer.LogEntries.cs b/src/WireMock.Net/Server/WireMockServer.LogEntries.cs index 10a9ad5d..2de80fcf 100644 --- a/src/WireMock.Net/Server/WireMockServer.LogEntries.cs +++ b/src/WireMock.Net/Server/WireMockServer.LogEntries.cs @@ -1,9 +1,7 @@ // Copyright © WireMock.Net using System; -using System.Collections; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; using JetBrains.Annotations; @@ -24,23 +22,20 @@ public event NotifyCollectionChangedEventHandler LogEntriesChanged remove => _logEntriesChanged -= value; } - /// <inheritdoc cref="IWireMockServer.LogEntries" /> + /// <inheritdoc /> [PublicAPI] - public IEnumerable<ILogEntry> LogEntries => new ReadOnlyCollection<LogEntry>(_options.LogEntries.ToList()); + public IReadOnlyList<ILogEntry> LogEntries => _options.LogEntries.ToArray(); + - /// <summary> - /// The search log-entries based on matchers. - /// </summary> - /// <param name="matchers">The matchers.</param> - /// <returns>The <see cref="IEnumerable"/>.</returns> + /// <inheritdoc /> [PublicAPI] - public IEnumerable<LogEntry> FindLogEntries(params IRequestMatcher[] matchers) + public IReadOnlyList<ILogEntry> FindLogEntries(params IRequestMatcher[] matchers) { Guard.NotNull(matchers); var results = new Dictionary<LogEntry, RequestMatchResult>(); - foreach (var log in _options.LogEntries.ToList()) + foreach (var log in _options.LogEntries.ToArray()) { var requestMatchResult = new RequestMatchResult(); foreach (var matcher in matchers) @@ -54,7 +49,10 @@ public IEnumerable<LogEntry> FindLogEntries(params IRequestMatcher[] matchers) } } - return new ReadOnlyCollection<LogEntry>(results.OrderBy(x => x.Value).Select(x => x.Key).ToList()); + return results + .OrderBy(x => x.Value) + .Select(x => x.Key) + .ToArray(); } /// <inheritdoc cref="IWireMockServer.ResetLogEntries" /> diff --git a/src/WireMock.Net/Server/WireMockServer.cs b/src/WireMock.Net/Server/WireMockServer.cs index 4eedf455..1d91f490 100644 --- a/src/WireMock.Net/Server/WireMockServer.cs +++ b/src/WireMock.Net/Server/WireMockServer.cs @@ -84,11 +84,11 @@ public partial class WireMockServer : IWireMockServer /// Gets the mappings. /// </summary> [PublicAPI] - public IEnumerable<IMapping> Mappings => _options.Mappings.Values.ToArray(); + public IReadOnlyList<IMapping> Mappings => _options.Mappings.Values.ToArray(); /// <inheritdoc cref="IWireMockServer.MappingModels" /> [PublicAPI] - public IEnumerable<MappingModel> MappingModels => ToMappingModels(); + public IReadOnlyList<MappingModel> MappingModels => ToMappingModels(); /// <summary> /// Gets the scenarios. diff --git a/test/WireMock.Net.Tests/WireMockServer.Admin.cs b/test/WireMock.Net.Tests/WireMockServer.Admin.cs index b1a919ef..aa4f518d 100644 --- a/test/WireMock.Net.Tests/WireMockServer.Admin.cs +++ b/test/WireMock.Net.Tests/WireMockServer.Admin.cs @@ -15,6 +15,7 @@ using WireMock.Client; using WireMock.Handlers; using WireMock.Logging; +using WireMock.Matchers; using WireMock.Matchers.Request; using WireMock.RequestBuilders; using WireMock.ResponseBuilders; @@ -258,7 +259,7 @@ public async Task WireMockServer_Admin_Mapping_WithoutPathOrUrl() // Assert var mapping = server.Mappings.First(m => !m.IsAdminInterface); - var request = (Request) mapping.RequestMatcher; + var request = (Request)mapping.RequestMatcher; var pathMatcher = request.GetRequestMessageMatcher<RequestMessagePathMatcher>(); pathMatcher.Should().BeNull(); @@ -428,6 +429,34 @@ public async Task WireMockServer_Admin_Logging_SetMaxRequestLogCount_To_0_Should server.Stop(); } + [Fact] + public async Task WireMockServer_Admin_Logging_FindLogEntries() + { + // Assign + using var client = new HttpClient(); + + // Act + using var server = WireMockServer.Start(); + + var tasks = new[] + { + client.GetAsync($"{server.Url}/foo1"), + client.PostAsync($"{server.Url}/foo2", new StringContent("test")), + client.GetAsync($"{server.Url}/foo3") + }; + + await Task.WhenAll(tasks).ConfigureAwait(false); + + // Act + var logEntries = server.FindLogEntries(new RequestMessageMethodMatcher("GET")); + + // Assert + logEntries.Should().HaveCount(2); + + logEntries.Single(le => le.RequestMessage.Path.EndsWith("foo1")).Should().NotBeNull(); + logEntries.Single(le => le.RequestMessage.Path.EndsWith("foo3")).Should().NotBeNull(); + } + [Fact] public void WireMockServer_Admin_WatchStaticMappings() {