diff --git a/Directory.Build.props b/Directory.Build.props index 25a3eb8b..b6c806f2 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ - 1.0.5 + 1.0.6 diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt index 1f936d0a..a39f929e 100644 --- a/GitHubReleaseNotes.txt +++ b/GitHubReleaseNotes.txt @@ -1,3 +1,3 @@ https://github.com/StefH/GitHubReleaseNotes -GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --version 1.0.5 \ No newline at end of file +GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --version 1.0.6 \ No newline at end of file diff --git a/src/WireMock.Net/Client/IFluentMockServerAdmin.cs b/src/WireMock.Net/Client/IFluentMockServerAdmin.cs index aa001128..430dfa4f 100644 --- a/src/WireMock.Net/Client/IFluentMockServerAdmin.cs +++ b/src/WireMock.Net/Client/IFluentMockServerAdmin.cs @@ -58,6 +58,14 @@ namespace WireMock.Client [Header("Content-Type", "application/json")] Task PostMappingAsync([Body] MappingModel mapping); + /// + /// Add new mappings. + /// + /// MappingModels + [Post("__admin/mappings")] + [Header("Content-Type", "application/json")] + Task PostMappingsAsync([Body] IList mappings); + /// /// Delete all mappings. /// diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs index 47f45175..8a0ced75 100644 --- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs +++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs @@ -1,3 +1,6 @@ +using JetBrains.Annotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; @@ -5,9 +8,6 @@ using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; -using JetBrains.Annotations; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using WireMock.Admin.Mappings; using WireMock.Admin.Scenarios; using WireMock.Admin.Settings; @@ -412,11 +412,21 @@ namespace WireMock.Server private ResponseMessage MappingsPost(RequestMessage requestMessage) { - Guid? guid; try { - var mappingModel = DeserializeObject(requestMessage); - guid = DeserializeAndAddOrUpdateMapping(mappingModel); + var mappingModels = DeserializeObjectArray(requestMessage); + if (mappingModels.Length == 1) + { + Guid? guid = DeserializeAndAddOrUpdateMapping(mappingModels[0]); + return ResponseMessageBuilder.Create("Mapping added", 201, guid); + } + + foreach (var mappingModel in mappingModels) + { + DeserializeAndAddOrUpdateMapping(mappingModel); + } + + return ResponseMessageBuilder.Create("Mappings added", 201); } catch (ArgumentException a) { @@ -428,8 +438,6 @@ namespace WireMock.Server _logger.Error("HttpStatusCode set to 500 {0}", e); return ResponseMessageBuilder.Create(e.ToString(), 500); } - - return ResponseMessageBuilder.Create("Mapping added", 201, guid); } private Guid? DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null) @@ -793,5 +801,23 @@ namespace WireMock.Server return default(T); } + + private T[] DeserializeObjectArray(RequestMessage requestMessage) + { + if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json) + { + var bodyAsJson = requestMessage.BodyData.BodyAsJson; + + if (bodyAsJson is JArray jArray) + { + return jArray.ToObject(); + } + + var value = ((JObject)requestMessage.BodyData.BodyAsJson).ToObject(); + return new[] { value }; + } + + return default(T[]); + } } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/FluentMockServerAdminRestClientTests.cs b/test/WireMock.Net.Tests/FluentMockServerAdminRestClientTests.cs index 490aecc1..cfaac4d9 100644 --- a/test/WireMock.Net.Tests/FluentMockServerAdminRestClientTests.cs +++ b/test/WireMock.Net.Tests/FluentMockServerAdminRestClientTests.cs @@ -1,9 +1,9 @@ -using System.Linq; +using NFluent; +using RestEase; +using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; -using NFluent; -using RestEase; using WireMock.Admin.Mappings; using WireMock.Admin.Settings; using WireMock.Client; @@ -19,7 +19,7 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_GetSettingsAsync() { - // Assign + // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); @@ -31,7 +31,7 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_PostSettingsAsync() { - // Assign + // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); @@ -44,7 +44,7 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_PutSettingsAsync() { - // Assign + // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); @@ -57,22 +57,15 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_PostMappingAsync() { - // Assign + // Arrange var server = FluentMockServer.StartWithAdminInterface(); var api = RestClient.For(server.Urls[0]); // Act var model = new MappingModel { - Request = new RequestModel - { - Path = "/1" - }, - Response = new ResponseModel - { - Body = "txt", - StatusCode = 200 - }, + Request = new RequestModel { Path = "/1" }, + Response = new ResponseModel { Body = "txt", StatusCode = 200 }, Priority = 500, Title = "test" }; @@ -90,10 +83,41 @@ namespace WireMock.Net.Tests server.Stop(); } + [Fact] + public async Task IFluentMockServerAdmin_PostMappingsAsync() + { + // Arrange + var server = FluentMockServer.StartWithAdminInterface(); + var api = RestClient.For(server.Urls[0]); + + // Act + var model1 = new MappingModel + { + Request = new RequestModel { Path = "/1" }, + Response = new ResponseModel { Body = "txt 1" }, + Title = "test 1" + }; + var model2 = new MappingModel + { + Request = new RequestModel { Path = "/2" }, + Response = new ResponseModel { Body = "txt 2" }, + Title = "test 2" + }; + var result = await api.PostMappingsAsync(new[] { model1, model2 }); + + // Assert + Check.That(result).IsNotNull(); + Check.That(result.Status).IsNotNull(); + Check.That(result.Guid).IsNull(); + Check.That(server.Mappings.Where(m => !m.IsAdminInterface)).HasSize(2); + + server.Stop(); + } + [Fact] public async Task IFluentMockServerAdmin_FindRequestsAsync() { - // given + // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, @@ -103,10 +127,10 @@ namespace WireMock.Net.Tests await new HttpClient().GetAsync(serverUrl + "/foo"); var api = RestClient.For(serverUrl); - // when + // Act var requests = await api.FindRequestsAsync(new RequestModel { Methods = new[] { "GET" } }); - // then + // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("GET"); @@ -117,7 +141,7 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_GetRequestsAsync() { - // given + // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, @@ -127,10 +151,10 @@ namespace WireMock.Net.Tests await new HttpClient().GetAsync(serverUrl + "/foo"); var api = RestClient.For(serverUrl); - // when + // Act var requests = await api.GetRequestsAsync(); - // then + // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("GET"); @@ -141,7 +165,7 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_GetRequestsAsync_JsonApi() { - // given + // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, @@ -159,13 +183,14 @@ namespace WireMock.Net.Tests request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(jsonApiContentType); var response = await new HttpClient().SendAsync(request); + Check.That(response).IsNotNull(); var api = RestClient.For(serverUrl); - // when + // Act var requests = await api.GetRequestsAsync(); - // then + // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("POST"); @@ -176,7 +201,7 @@ namespace WireMock.Net.Tests [Fact] public async Task IFluentMockServerAdmin_GetRequestsAsync_Json() { - // given + // Arrange var server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, @@ -193,13 +218,14 @@ namespace WireMock.Net.Tests request.Content = new StringContent(data); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(jsonApiContentType); var response = await new HttpClient().SendAsync(request); + Check.That(response).IsNotNull(); var api = RestClient.For(serverUrl); - // when + // Act var requests = await api.GetRequestsAsync(); - // then + // Assert Check.That(requests).HasSize(1); var requestLogged = requests.First(); Check.That(requestLogged.Request.Method).IsEqualTo("POST");