diff --git a/examples/WireMock.Net.Console.NETCoreApp/WireMock.Net.Console.NETCoreApp.csproj b/examples/WireMock.Net.Console.NETCoreApp/WireMock.Net.Console.NETCoreApp.csproj index 4b6c9735..bbe78311 100644 --- a/examples/WireMock.Net.Console.NETCoreApp/WireMock.Net.Console.NETCoreApp.csproj +++ b/examples/WireMock.Net.Console.NETCoreApp/WireMock.Net.Console.NETCoreApp.csproj @@ -6,16 +6,12 @@ ../../WireMock.Net-Logo.ico - - - - - + PreserveNewest diff --git a/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/791a3f31-6946-4ce7-8e6f-0237c7443275.json b/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/791a3f31-6946-4ce7-8e6f-0237c7443275.json index 35a1c17b..d7a6cbdd 100644 --- a/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/791a3f31-6946-4ce7-8e6f-0237c7443275.json +++ b/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/791a3f31-6946-4ce7-8e6f-0237c7443275.json @@ -3,14 +3,7 @@ "Title": "", "Priority": 0, "Request": { - "Path": { - "Matchers": [ - { - "Name": "WildcardMatcher", - "Pattern": "/proxy-google-test-post" - } - ] - }, + "Path": "/proxy-google-test-post", "Methods": [ "post" ], diff --git a/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json b/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json new file mode 100644 index 00000000..dd501800 --- /dev/null +++ b/examples/WireMock.Net.Console.NETCoreApp/__admin/mappings/873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json @@ -0,0 +1,19 @@ +{ + "Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b", + "Priority": 4, + "Request": { + "Path": {}, + "Methods": [ + "get" + ] + }, + "Response": { + "StatusCode": 200, + "BodyDestination": "SameAsSource", + "Body": "NO PATH OR URL", + "UseTransformer": false, + "Headers": { + "Content-Type": "application/json" + } + } +} \ No newline at end of file diff --git a/examples/WireMock.Net.ConsoleApplication/MainApp.cs b/examples/WireMock.Net.ConsoleApplication/MainApp.cs index a44bf4aa..965b058b 100644 --- a/examples/WireMock.Net.ConsoleApplication/MainApp.cs +++ b/examples/WireMock.Net.ConsoleApplication/MainApp.cs @@ -38,6 +38,14 @@ namespace WireMock.Net.ConsoleApplication server.AllowPartialMapping(); + server + .Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet()) + .AtPriority(4) + .RespondWith(Response.Create() + .WithStatusCode(200) + .WithHeader("Content-Type", "application/json") + .WithBody(@"{ ""result"": ""Contains x with FUNC 200""}")); + server .Given(Request.Create() .UsingGet() @@ -53,7 +61,7 @@ namespace WireMock.Net.ConsoleApplication .WithPath("/proxy-execute-keep-alive") ) .RespondWith(Response.Create() - .WithProxy(new ProxyAndRecordSettings { Url = "http://localhost:9999", BlackListedHeaders = new [] { "Keep-Alive" } }) + .WithProxy(new ProxyAndRecordSettings { Url = "http://localhost:9999", BlackListedHeaders = new[] { "Keep-Alive" } }) .WithHeader("Keep-Alive-Test", "stef") ); @@ -144,8 +152,10 @@ namespace WireMock.Net.ConsoleApplication server .Given(Request.Create().WithPath("/file_rel").UsingGet()) + .WithGuid("0000aaaa-fcf4-4256-a0d3-1c76e4862947") .RespondWith(Response.Create() - .WithBodyFromFile("Program.cs", false) + .WithHeader("Content-Type", "application/xml") + .WithBodyFromFile("WireMock.Net.xml", false) ); server @@ -176,14 +186,6 @@ namespace WireMock.Net.ConsoleApplication .WithStatusCode(200) .WithBody("hi")); - server - .Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet()) - .AtPriority(4) - .RespondWith(Response.Create() - .WithStatusCode(200) - .WithHeader("Content-Type", "application/json") - .WithBody(@"{ ""result"": ""Contains x with FUNC 200""}")); - server .Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e"))) .AtPriority(999) @@ -284,7 +286,7 @@ namespace WireMock.Net.ConsoleApplication .Given(Request.Create().WithPath("/jsonpathtestTokenJson").UsingPost()) .RespondWith(Response.Create() .WithHeader("Content-Type", "application/json") - .WithBodyAsJson(new { status = "OK", url = "{{request.url}}", transformed = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" } ) + .WithBodyAsJson(new { status = "OK", url = "{{request.url}}", transformed = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" }) .WithTransformer() ); diff --git a/examples/WireMock.Net.ConsoleApplication/WireMock.Net.Console.NET452.csproj b/examples/WireMock.Net.ConsoleApplication/WireMock.Net.Console.NET452.csproj index 5f0a26a8..86f6fd3a 100644 --- a/examples/WireMock.Net.ConsoleApplication/WireMock.Net.Console.NET452.csproj +++ b/examples/WireMock.Net.ConsoleApplication/WireMock.Net.Console.NET452.csproj @@ -71,6 +71,9 @@ PreserveNewest + + PreserveNewest + diff --git a/examples/WireMock.Net.ConsoleApplication/__admin/mappings/873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json b/examples/WireMock.Net.ConsoleApplication/__admin/mappings/873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json new file mode 100644 index 00000000..dd501800 --- /dev/null +++ b/examples/WireMock.Net.ConsoleApplication/__admin/mappings/873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json @@ -0,0 +1,19 @@ +{ + "Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b", + "Priority": 4, + "Request": { + "Path": {}, + "Methods": [ + "get" + ] + }, + "Response": { + "StatusCode": 200, + "BodyDestination": "SameAsSource", + "Body": "NO PATH OR URL", + "UseTransformer": false, + "Headers": { + "Content-Type": "application/json" + } + } +} \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/JSONPathMatcher.cs b/src/WireMock.Net/Matchers/JSONPathMatcher.cs index 5a4a6241..0b25790e 100644 --- a/src/WireMock.Net/Matchers/JSONPathMatcher.cs +++ b/src/WireMock.Net/Matchers/JSONPathMatcher.cs @@ -63,7 +63,9 @@ namespace WireMock.Matchers public double IsMatch(object input) { double match = MatchScores.Mismatch; - if (input != null) + + // When input is null or byte[], return Mismatch. + if (input != null && !(input is byte[])) { try { diff --git a/src/WireMock.Net/Matchers/JsonMatcher.cs b/src/WireMock.Net/Matchers/JsonMatcher.cs index d39477c3..4cfff630 100644 --- a/src/WireMock.Net/Matchers/JsonMatcher.cs +++ b/src/WireMock.Net/Matchers/JsonMatcher.cs @@ -65,7 +65,9 @@ namespace WireMock.Matchers public double IsMatch(object input) { bool match = false; - if (input != null) + + // When input is null or byte[], return Mismatch. + if (input != null && !(input is byte[])) { try { diff --git a/src/WireMock.Net/Serialization/MatcherMapper.cs b/src/WireMock.Net/Serialization/MatcherMapper.cs index 2c69104b..8d513718 100644 --- a/src/WireMock.Net/Serialization/MatcherMapper.cs +++ b/src/WireMock.Net/Serialization/MatcherMapper.cs @@ -21,7 +21,7 @@ namespace WireMock.Serialization string matcherName = parts[0]; string matcherType = parts.Length > 1 ? parts[1] : null; - string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast().ToArray() : new [] { matcher.Pattern as string }; + string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast().ToArray() : new[] { matcher.Pattern as string }; MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch; switch (matcherName) @@ -39,7 +39,7 @@ namespace WireMock.Serialization return new JsonPathMatcher(matchBehaviour, stringPatterns); case "XPathMatcher": - return new XPathMatcher(matchBehaviour, (string) matcher.Pattern); + return new XPathMatcher(matchBehaviour, (string)matcher.Pattern); case "WildcardMatcher": return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); @@ -51,7 +51,7 @@ namespace WireMock.Serialization throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported."); } - return new SimMetricsMatcher(matchBehaviour, (string) matcher.Pattern, type); + return new SimMetricsMatcher(matchBehaviour, (string)matcher.Pattern, type); default: throw new NotSupportedException($"Matcher '{matcherName}' is not supported."); diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs index c98fdd97..fd176d73 100644 --- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs +++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs @@ -121,7 +121,15 @@ namespace WireMock.Server foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f)) { _logger.Info("Reading Static MappingFile : '{0}'", filename); - ReadStaticMappingAndAddOrUpdate(filename); + + try + { + ReadStaticMappingAndAddOrUpdate(filename); + } + catch + { + _logger.Error("Static MappingFile : '{0}' could not be read. This file will be skipped.", filename); + } } } @@ -316,9 +324,9 @@ namespace WireMock.Server Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray())); var mappingModel = DeserializeObject(requestMessage); - DeserializeAndAddOrUpdateMapping(mappingModel, guid); + Guid? guidFromPut = DeserializeAndAddOrUpdateMapping(mappingModel, guid); - return ResponseMessageBuilder.Create("Mapping added or updated", 200, guid); + return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut); } private ResponseMessage MappingDelete(RequestMessage requestMessage) @@ -401,13 +409,18 @@ namespace WireMock.Server return ResponseMessageBuilder.Create("Mapping added", 201, guid); } - private Guid DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null) + private Guid? DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null) { Check.NotNull(mappingModel, nameof(mappingModel)); Check.NotNull(mappingModel.Request, nameof(mappingModel.Request)); Check.NotNull(mappingModel.Response, nameof(mappingModel.Response)); - var requestBuilder = InitRequestBuilder(mappingModel.Request); + var requestBuilder = InitRequestBuilder(mappingModel.Request, true); + if (requestBuilder == null) + { + return null; + } + var responseBuilder = InitResponseBuilder(mappingModel.Response); var respondProvider = Given(requestBuilder); @@ -511,7 +524,7 @@ namespace WireMock.Server { var requestModel = DeserializeObject(requestMessage); - var request = (Request)InitRequestBuilder(requestModel); + var request = (Request)InitRequestBuilder(requestModel, false); var dict = new Dictionary(); foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/"))) @@ -551,7 +564,7 @@ namespace WireMock.Server } #endregion - private IRequestBuilder InitRequestBuilder(RequestModel requestModel) + private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired) { IRequestBuilder requestBuilder = Request.Create(); @@ -571,11 +584,13 @@ namespace WireMock.Server } } + bool pathOrUrlmatchersValid = false; if (requestModel.Path != null) { if (requestModel.Path is string path) { requestBuilder = requestBuilder.WithPath(path); + pathOrUrlmatchersValid = true; } else { @@ -583,15 +598,16 @@ namespace WireMock.Server if (pathModel?.Matchers != null) { requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast().ToArray()); + pathOrUrlmatchersValid = true; } } } - - if (requestModel.Url != null) + else if (requestModel.Url != null) { if (requestModel.Url is string url) { requestBuilder = requestBuilder.WithUrl(url); + pathOrUrlmatchersValid = true; } else { @@ -599,10 +615,17 @@ namespace WireMock.Server if (urlModel?.Matchers != null) { requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast().ToArray()); + pathOrUrlmatchersValid = true; } } } + if (pathOrUrlRequired && !pathOrUrlmatchersValid) + { + _logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added."); + return null; + } + if (requestModel.Methods != null) { requestBuilder = requestBuilder.UsingMethod(requestModel.Methods); diff --git a/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs index 85bc18d6..0dca72b5 100644 --- a/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs @@ -33,6 +33,20 @@ namespace WireMock.Net.Tests.Matchers Check.That(value).Equals("{}"); } + [Fact] + public void JsonMatcher_IsMatch_ByteArray() + { + // Assign + var bytes = new byte[0]; + var matcher = new JsonMatcher(""); + + // Act + double match = matcher.IsMatch(bytes); + + // Assert + Check.That(match).IsEqualTo(0); + } + [Fact] public void JsonMatcher_IsMatch_NullString() { diff --git a/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs index 8d25cc1b..a1ffe2ce 100644 --- a/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/JsonPathMatcherTests.cs @@ -33,6 +33,20 @@ namespace WireMock.Net.Tests.Matchers Check.That(patterns).ContainsExactly("X"); } + [Fact] + public void JsonPathMatcher_IsMatch_ByteArray() + { + // Assign + var bytes = new byte[0]; + var matcher = new JsonPathMatcher(""); + + // Act + double match = matcher.IsMatch(bytes); + + // Assert + Check.That(match).IsEqualTo(0); + } + [Fact] public void JsonPathMatcher_IsMatch_NullString() {