diff --git a/src/WireMock.Net.Abstractions/Admin/Requests/LogEntryModel.cs b/src/WireMock.Net.Abstractions/Admin/Requests/LogEntryModel.cs
index 9c4ffefa0..aa895697e 100644
--- a/src/WireMock.Net.Abstractions/Admin/Requests/LogEntryModel.cs
+++ b/src/WireMock.Net.Abstractions/Admin/Requests/LogEntryModel.cs
@@ -15,12 +15,12 @@ public class LogEntryModel
///
/// The request.
///
- public LogRequestModel Request { get; set; }
+ public required LogRequestModel Request { get; init; }
///
/// The response.
///
- public LogResponseModel Response { get; set; }
+ public required LogResponseModel Response { get; init; }
///
/// The mapping unique identifier.
diff --git a/src/WireMock.Net.Abstractions/WireMock.Net.Abstractions.csproj b/src/WireMock.Net.Abstractions/WireMock.Net.Abstractions.csproj
index f6c9f501b..29aa28054 100644
--- a/src/WireMock.Net.Abstractions/WireMock.Net.Abstractions.csproj
+++ b/src/WireMock.Net.Abstractions/WireMock.Net.Abstractions.csproj
@@ -43,6 +43,11 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/src/WireMock.Net.RestClient/IWireMockAdminApi.cs b/src/WireMock.Net.RestClient/IWireMockAdminApi.cs
index 92fdcb709..e8f07c2e0 100644
--- a/src/WireMock.Net.RestClient/IWireMockAdminApi.cs
+++ b/src/WireMock.Net.RestClient/IWireMockAdminApi.cs
@@ -178,7 +178,7 @@ public interface IWireMockAdminApi
/// Get a request based on the guid
///
/// The Guid
- /// MappingModel
+ /// LogEntryModel
/// The optional cancellationToken.
[Get("requests/{guid}")]
Task GetRequestAsync([Path] Guid guid, CancellationToken cancellationToken = default);
@@ -192,7 +192,7 @@ public interface IWireMockAdminApi
Task DeleteRequestAsync([Path] Guid guid, CancellationToken cancellationToken = default);
///
- /// Find a request based on the criteria
+ /// Find requests based on the criteria ()
///
/// The RequestModel
/// The optional cancellationToken.
@@ -200,6 +200,14 @@ public interface IWireMockAdminApi
[Header("Content-Type", "application/json")]
Task> FindRequestsAsync([Body] RequestModel model, CancellationToken cancellationToken = default);
+ ///
+ /// Find a request based on the Mapping Guid.
+ ///
+ /// The Mapping Guid
+ /// The optional cancellationToken.
+ [Get("requests/find")]
+ Task FindRequestByMappingGuidAsync([Query] Guid mappingGuid, CancellationToken cancellationToken = default);
+
///
/// Get all scenarios
///
diff --git a/src/WireMock.Net/Server/WireMockServer.Admin.cs b/src/WireMock.Net/Server/WireMockServer.Admin.cs
index a0fce63e8..15c225d7f 100644
--- a/src/WireMock.Net/Server/WireMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/WireMockServer.Admin.cs
@@ -99,6 +99,7 @@ private void InitAdmin()
// __admin/requests/find
Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestsFind));
+ Given(Request.Create().WithPath(AdminRequests + "/find").UsingGet().WithParam("mappingGuid", new NotNullOrEmptyMatcher())).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(RequestFindByMappingGuid));
// __admin/scenarios
Given(Request.Create().WithPath(AdminScenarios).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosGet));
@@ -436,7 +437,7 @@ private IResponseMessage MappingsPost(IRequestMessage requestMessage)
var mappingModels = DeserializeRequestMessageToArray(requestMessage);
if (mappingModels.Length == 1)
{
- Guid? guid = ConvertMappingAndRegisterAsRespondProvider(mappingModels[0]);
+ var guid = ConvertMappingAndRegisterAsRespondProvider(mappingModels[0]);
return ResponseMessageBuilder.Create(201, "Mapping added", guid);
}
@@ -535,7 +536,7 @@ private IResponseMessage RequestGet(IRequestMessage requestMessage)
{
if (TryParseGuidFromRequestMessage(requestMessage, out var guid))
{
- var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
+ var entry = LogEntries.SingleOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
if (entry is { })
{
var model = new LogEntryMapper(_options).Map(entry);
@@ -600,6 +601,26 @@ private IResponseMessage RequestsFind(IRequestMessage requestMessage)
return ToJson(result);
}
+
+ private IResponseMessage RequestFindByMappingGuid(IRequestMessage requestMessage)
+ {
+ if (requestMessage.Query != null &&
+ requestMessage.Query.TryGetValue("mappingGuid", out var value) &&
+ Guid.TryParse(value.ToString(), out var mappingGuid)
+ )
+ {
+ var logEntry = LogEntries.SingleOrDefault(le => !le.RequestMessage.Path.StartsWith("/__admin/") && le.MappingGuid == mappingGuid);
+ if (logEntry != null)
+ {
+ var logEntryMapper = new LogEntryMapper(_options);
+ return ToJson(logEntryMapper.Map(logEntry));
+ }
+
+ return ResponseMessageBuilder.Create(HttpStatusCode.OK);
+ }
+
+ return ResponseMessageBuilder.Create(HttpStatusCode.BadRequest);
+ }
#endregion Requests/find
#region Scenarios
diff --git a/src/WireMock.Net/WireMock.Net.csproj b/src/WireMock.Net/WireMock.Net.csproj
index 895c5acf4..bcb52ca51 100644
--- a/src/WireMock.Net/WireMock.Net.csproj
+++ b/src/WireMock.Net/WireMock.Net.csproj
@@ -72,13 +72,6 @@
-
-
- all
- runtime; build; native; contentfiles; analyzers
-
-
-
diff --git a/test/WireMock.Net.Tests/WireMockAdminApiTests.cs b/test/WireMock.Net.Tests/WireMockAdminApiTests.cs
index 43f83a8e4..b25018321 100644
--- a/test/WireMock.Net.Tests/WireMockAdminApiTests.cs
+++ b/test/WireMock.Net.Tests/WireMockAdminApiTests.cs
@@ -234,6 +234,10 @@ public async Task IWireMockAdminApi_FindRequestsAsync()
StartAdminInterface = true,
Logger = new WireMockNullLogger()
});
+ server
+ .Given(Request.Create().WithPath("/foo").UsingGet())
+ .RespondWith(Response.Create());
+
var serverUrl = "http://localhost:" + server.Ports[0];
await new HttpClient().GetAsync(serverUrl + "/foo").ConfigureAwait(false);
var api = RestClient.For(serverUrl);
@@ -242,11 +246,82 @@ public async Task IWireMockAdminApi_FindRequestsAsync()
var requests = await api.FindRequestsAsync(new RequestModel { Methods = new[] { "GET" } }).ConfigureAwait(false);
// Assert
- Check.That(requests).HasSize(1);
+ requests.Should().HaveCount(1);
var requestLogged = requests.First();
- Check.That(requestLogged.Request.Method).IsEqualTo("GET");
- Check.That(requestLogged.Request.Body).IsNull();
- Check.That(requestLogged.Request.Path).IsEqualTo("/foo");
+ requestLogged.Request.Method.Should().Be("GET");
+ requestLogged.Request.Body.Should().BeNull();
+ requestLogged.Request.Path.Should().Be("/foo");
+ }
+
+ [Fact]
+ public async Task IWireMockAdminApi_FindRequestByMappingGuidAsync_Found()
+ {
+ // Arrange
+ var mappingGuid = Guid.NewGuid();
+ var server = WireMockServer.Start(new WireMockServerSettings
+ {
+ StartAdminInterface = true,
+ Logger = new WireMockNullLogger()
+ });
+ server
+ .Given(Request.Create().WithPath("/foo").UsingGet())
+ .WithGuid(mappingGuid)
+ .RespondWith(Response.Create());
+
+ var serverUrl = "http://localhost:" + server.Ports[0];
+ await new HttpClient().GetAsync(serverUrl + "/foo").ConfigureAwait(false);
+ var api = RestClient.For(serverUrl);
+
+ // Act
+ var logEntryModel = await api.FindRequestByMappingGuidAsync(mappingGuid).ConfigureAwait(false);
+
+ // Assert
+ logEntryModel.Should().NotBeNull();
+ logEntryModel!.Request.Method.Should().Be("GET");
+ logEntryModel!.Request.Body.Should().BeNull();
+ logEntryModel!.Request.Path.Should().Be("/foo");
+ }
+
+ [Fact]
+ public async Task IWireMockAdminApi_FindRequestByMappingGuidAsync_NotFound()
+ {
+ // Arrange
+ var server = WireMockServer.Start(new WireMockServerSettings
+ {
+ StartAdminInterface = true,
+ Logger = new WireMockNullLogger()
+ });
+ server
+ .Given(Request.Create().WithPath("/foo").UsingGet())
+ .WithGuid(Guid.NewGuid())
+ .RespondWith(Response.Create());
+
+ var serverUrl = "http://localhost:" + server.Ports[0];
+ await new HttpClient().GetAsync(serverUrl + "/foo").ConfigureAwait(false);
+ var api = RestClient.For(serverUrl);
+
+ // Act
+ var logEntryModel = await api.FindRequestByMappingGuidAsync(Guid.NewGuid()).ConfigureAwait(false);
+
+ // Assert
+ logEntryModel.Should().BeNull();
+ }
+
+ [Fact]
+ public async Task IWireMockAdminApi_FindRequestByMappingGuidAsync_Invalid_ShouldReturnBadRequest()
+ {
+ // Arrange
+ var server = WireMockServer.Start(new WireMockServerSettings
+ {
+ StartAdminInterface = true,
+ Logger = new WireMockNullLogger()
+ });
+
+ // Act
+ var result = await server.CreateClient().GetAsync("/__admin/requests/find?mappingGuid=x");
+
+ // Assert
+ result.StatusCode.Should().Be(HttpStatusCode.BadRequest);
}
[Fact]
@@ -815,7 +890,7 @@ public async Task IWireMockAdminApi_GetMappingsCode()
.RespondWith(
Response.Create()
.WithStatusCode(HttpStatusCode.AlreadyReported)
- .WithBodyAsJson(new { @as = 1, b=1.2, d=true, e=false, f=new[]{1,2,3,4}, g= new{z1=1, z2=2, z3=new []{"a","b","c"}, z4=new[]{new {a=1, b=2},new {a=2, b=3}}}, date_field = new DateTime(2023,05,08,11,20,19), string_field_with_date="2021-03-13T21:04:00Z", multiline_text= @"This
+ .WithBodyAsJson(new { @as = 1, b = 1.2, d = true, e = false, f = new[] { 1, 2, 3, 4 }, g = new { z1 = 1, z2 = 2, z3 = new[] { "a", "b", "c" }, z4 = new[] { new { a = 1, b = 2 }, new { a = 2, b = 3 } } }, date_field = new DateTime(2023, 05, 08, 11, 20, 19), string_field_with_date = "2021-03-13T21:04:00Z", multiline_text = @"This
is
multiline
text
@@ -826,7 +901,7 @@ public async Task IWireMockAdminApi_GetMappingsCode()
.Given(
Request.Create()
.WithPath("/foo3")
- .WithBody(new JsonPartialMatcher(new { a=1, b=2}))
+ .WithBody(new JsonPartialMatcher(new { a = 1, b = 2 }))
.UsingPost()
)
.WithGuid(guid4)
diff --git a/test/WireMock.Net.Tests/WireMockServer.Proxy.cs b/test/WireMock.Net.Tests/WireMockServer.Proxy.cs
index 1d7240eca..1504b6369 100644
--- a/test/WireMock.Net.Tests/WireMockServer.Proxy.cs
+++ b/test/WireMock.Net.Tests/WireMockServer.Proxy.cs
@@ -117,7 +117,7 @@ public async Task WireMockServer_Proxy_AdminTrue_With_SaveMapping_Is_True_And_Sa
}
// Assert
- server.Mappings.Should().HaveCount(34);
+ server.Mappings.Should().HaveCount(35);
}
[Fact]
diff --git a/test/WireMock.Net.Tests/WireMockServer.Settings.cs b/test/WireMock.Net.Tests/WireMockServer.Settings.cs
index e0974cb25..d1e8e9c94 100644
--- a/test/WireMock.Net.Tests/WireMockServer.Settings.cs
+++ b/test/WireMock.Net.Tests/WireMockServer.Settings.cs
@@ -81,7 +81,7 @@ public void WireMockServer_WireMockServerSettings_PriorityFromAllAdminMappingsIs
// Assert
server.Mappings.Should().NotBeNull();
- server.Mappings.Should().HaveCount(32);
+ server.Mappings.Should().HaveCount(33);
server.Mappings.All(m => m.Priority == WireMockConstants.AdminPriority).Should().BeTrue();
}
@@ -100,9 +100,9 @@ public void WireMockServer_WireMockServerSettings_ProxyAndRecordSettings_ProxyPr
// Assert
server.Mappings.Should().NotBeNull();
- server.Mappings.Should().HaveCount(33);
+ server.Mappings.Should().HaveCount(34);
- server.Mappings.Count(m => m.Priority == WireMockConstants.AdminPriority).Should().Be(32);
+ server.Mappings.Count(m => m.Priority == WireMockConstants.AdminPriority).Should().Be(33);
server.Mappings.Count(m => m.Priority == WireMockConstants.ProxyPriority).Should().Be(1);
}