Fix new Delete with body missing from IWireMockAdminApi interface (#413)

* Fix new Delete with body missing from IWireMockAdminApi interface

* Admin Delete with mappings in body (#409)

* Add unit test for delete with body

* change order of checks for readability. looks nicer.

* Allow body in DELETE requests

* Fix unit tests according to DELETE supporting body

* Re-run CI

* Fix DELETE with body unit test

* Fix ElementAt index in mappings list

* Fix DELETE with body unit test

* Fix theory tag must be accompanied by some InlineData or Member

* Fix didn't use correct checking syntax

* Fix wrap entire unit test in if region
This commit is contained in:
Noah Lerner
2020-02-05 20:11:44 +02:00
committed by GitHub
parent 1df4502631
commit 32248b6585
6 changed files with 131 additions and 10 deletions

View File

@@ -74,6 +74,14 @@ namespace WireMock.Client
[Delete("mappings")]
Task<StatusModel> DeleteMappingsAsync();
/// <summary>
/// Delete mappings according to GUIDs
/// </summary>
/// <param name="mappings">MappingModels</param>
[Delete("mappings")]
[Header("Content-Type", "application/json")]
Task<StatusModel> DeleteMappingsAsync([Body] IList<MappingModel> mappings);
/// <summary>
/// Delete (reset) all mappings.
/// </summary>

View File

@@ -555,11 +555,63 @@ namespace WireMock.Server
private ResponseMessage MappingsDelete(RequestMessage requestMessage)
{
ResetMappings();
if (!string.IsNullOrEmpty(requestMessage.Body))
{
var deletedGuids = MappingsDeleteMappingFromBody(requestMessage);
if (deletedGuids != null)
{
return ResponseMessageBuilder.Create($"Mappings deleted. Affected GUIDs: [{string.Join(", ", deletedGuids.ToArray())}]");
}
else
{
// return bad request
return ResponseMessageBuilder.Create("Poorly formed mapping JSON.", 400);
}
}
else
{
ResetMappings();
ResetScenarios();
ResetScenarios();
return ResponseMessageBuilder.Create("Mappings deleted");
return ResponseMessageBuilder.Create("Mappings deleted");
}
}
private IEnumerable<Guid> MappingsDeleteMappingFromBody(RequestMessage requestMessage)
{
var deletedGuids = new List<Guid>();
try
{
var mappingModels = DeserializeRequestMessageToArray<MappingModel>(requestMessage);
foreach (var mappingModel in mappingModels)
{
if (mappingModel.Guid.HasValue)
{
if (DeleteMapping(mappingModel.Guid.Value))
{
deletedGuids.Add(mappingModel.Guid.Value);
}
else
{
_settings.Logger.Debug($"Did not find/delete mapping with GUID: {mappingModel.Guid.Value}.");
}
}
}
}
catch (ArgumentException a)
{
_settings.Logger.Error("ArgumentException: {0}", a);
return null;
}
catch (Exception e)
{
_settings.Logger.Error("Exception: {0}", e);
return null;
}
return deletedGuids;
}
private ResponseMessage MappingsReset(RequestMessage requestMessage)
@@ -873,7 +925,7 @@ namespace WireMock.Server
DetectedBodyType = BodyType.String,
BodyAsString = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _jsonSerializerSettings)
},
StatusCode = (int) HttpStatusCode.OK,
StatusCode = (int)HttpStatusCode.OK,
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>(ContentTypeJson) } }
};
}

View File

@@ -34,7 +34,7 @@ namespace WireMock.Util
{ "GET", false },
{ "PUT", true },
{ "POST", true },
{ "DELETE", false },
{ "DELETE", true },
{ "TRACE", false },
{ "OPTIONS", true },
{ "CONNECT", false },

View File

@@ -148,7 +148,7 @@ Content-Type: text/html
[InlineData("GET", false)]
[InlineData("PUT", true)]
[InlineData("POST", true)]
[InlineData("DELETE", false)]
[InlineData("DELETE", true)]
[InlineData("TRACE", false)]
[InlineData("OPTIONS", true)]
[InlineData("CONNECT", false)]

View File

@@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Moq;
using Newtonsoft.Json;
@@ -42,7 +45,6 @@ namespace WireMock.Net.Tests
public void WireMockServer_Admin_ResetMappings()
{
var server = WireMockServer.Start();
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings");
server.ReadStaticMappings(folder);
@@ -404,5 +406,64 @@ namespace WireMock.Net.Tests
staticMappingHandlerMock.Verify(m => m.FolderExists("folder"), Times.Once);
staticMappingHandlerMock.Verify(m => m.WriteMappingFile(Path.Combine("folder", guid + ".json"), It.IsAny<string>()), Times.Once);
}
[Fact]
public async void WireMockServer_Admin_DeleteMappings()
{
// Arrange
var server = WireMockServer.Start(new WireMockServerSettings
{
StartAdminInterface = true,
ReadStaticMappings = false,
WatchStaticMappings = false,
WatchStaticMappingsInSubdirectories = false
});
server
.Given(Request.Create().WithPath("/path1"))
.AtPriority(0)
.RespondWith(Response.Create().WithStatusCode(200));
server
.Given(Request.Create().WithPath("/path2"))
.AtPriority(1)
.RespondWith(Response.Create().WithStatusCode(200));
server
.Given(Request.Create().WithPath("/path3"))
.AtPriority(2)
.RespondWith(Response.Create().WithStatusCode(200));
Check.That(server.MappingModels.Count()).Equals(3);
Guid? guid1 = server.MappingModels.ElementAt(0).Guid;
Guid? guid2 = server.MappingModels.ElementAt(1).Guid;
Guid? guid3 = server.MappingModels.ElementAt(2).Guid;
Check.That(guid1).IsNotNull();
Check.That(guid2).IsNotNull();
Check.That(guid3).IsNotNull();
string guidsJsonBody = $"[" +
$"{{\"Guid\": \"{guid1}\"}}," +
$"{{\"Guid\": \"{guid2}\"}}" +
$"]";
// Act
var request = new HttpRequestMessage()
{
Method = HttpMethod.Delete,
RequestUri = new Uri($"http://localhost:{server.Ports[0]}/__admin/mappings"),
Content = new StringContent(guidsJsonBody, Encoding.UTF8, "application/json")
};
var response = await new HttpClient().SendAsync(request);
// Assert
IEnumerable<Guid> guids = server.MappingModels.Select(mapping => mapping.Guid.Value);
Check.That(guids.Contains(guid1.Value)).IsFalse();
Check.That(guids.Contains(guid2.Value)).IsFalse();
Check.That(guids.Contains(guid3.Value)).IsTrue();
Check.That(response.StatusCode).Equals(HttpStatusCode.OK);
Check.That(await response.Content.ReadAsStringAsync()).Equals($"{{\"Status\":\"Mappings deleted. Affected GUIDs: [{guid1}, {guid2}]\"}}");
}
}
}

View File

@@ -160,12 +160,10 @@ namespace WireMock.Net.Tests
Check.That(response.Headers.Contains("Transfer-Encoding")).IsFalse();
}
[Theory]
[InlineData("DELETE")]
#if !NET452
[Theory]
[InlineData("TRACE")]
[InlineData("GET")]
#endif
public async Task WireMockServer_Should_exclude_body_for_methods_where_body_is_definitely_disallowed(string method)
{
// Assign
@@ -189,12 +187,14 @@ namespace WireMock.Net.Tests
// Assert
Check.That(response.StatusCode).Equals(HttpStatusCode.OK);
}
#endif
[Theory]
[InlineData("POST")]
[InlineData("PUT")]
[InlineData("OPTIONS")]
[InlineData("REPORT")]
[InlineData("DELETE")]
[InlineData("SOME-UNKNOWN-METHOD")] // default behavior for unknown methods is to allow a body (see BodyParser.ShouldParseBody)
public async Task WireMockServer_Should_not_exclude_body_for_supported_methods(string method)
{