diff --git a/WireMock.Net Solution.sln b/WireMock.Net Solution.sln index a896255c8..14ca823f9 100644 --- a/WireMock.Net Solution.sln +++ b/WireMock.Net Solution.sln @@ -54,8 +54,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.StandAlone.Net EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Service", "examples\Wiremock.Net.Service\WireMock.Net.Service.csproj", "{7F0B2446-0363-4720-AF46-F47F83B557DC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.HeadersTest", "examples\WireMock.Net.Console.HeadersTest\WireMock.Net.Console.HeadersTest.csproj", "{B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net461.Classic", "examples\WireMock.Net.Console.Net461.Classic\WireMock.Net.Console.Net461.Classic.csproj", "{1261BB9B-A7D4-456C-8985-3CE560361B8E}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net452.Classic", "examples\WireMock.Net.Console.Net452.Classic\WireMock.Net.Console.Net452.Classic.csproj", "{668F689E-57B4-422E-8846-C0FF643CA268}" @@ -120,10 +118,6 @@ Global {7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|Any CPU.Build.0 = Release|Any CPU - {B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Release|Any CPU.Build.0 = Release|Any CPU {1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1261BB9B-A7D4-456C-8985-3CE560361B8E}.Debug|Any CPU.Build.0 = Debug|Any CPU {1261BB9B-A7D4-456C-8985-3CE560361B8E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -154,7 +148,6 @@ Global {23A9AA3C-40FC-42AA-8A5E-05899795A1C6} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} {3C279524-DB73-4DE3-BEF1-F2B2958C9F65} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} {7F0B2446-0363-4720-AF46-F47F83B557DC} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} - {B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} {1261BB9B-A7D4-456C-8985-3CE560361B8E} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} {668F689E-57B4-422E-8846-C0FF643CA268} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} {83645809-9E01-4E81-8733-BA9497554ABF} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A} diff --git a/examples/WireMock.Net.Console.HeadersTest/Program.cs b/examples/WireMock.Net.Console.HeadersTest/Program.cs deleted file mode 100644 index ea8480ba3..000000000 --- a/examples/WireMock.Net.Console.HeadersTest/Program.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.IO; -using System.Reflection; -using log4net; -using log4net.Config; -using log4net.Repository; -using Newtonsoft.Json; -using WireMock.Logging; -using WireMock.RequestBuilders; -using WireMock.ResponseBuilders; -using WireMock.Server; -using WireMock.Settings; - -namespace WireMock.Net.Console.NETCoreApp -{ - static class Program - { - private static readonly ILoggerRepository LogRepository = LogManager.GetRepository(Assembly.GetEntryAssembly()); - private static readonly ILog Log = LogManager.GetLogger(typeof(Program)); - - static void Main(params string[] args) - { - XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config")); - - string url = "http://localhost:9999/"; - - var server = FluentMockServer.Start(new FluentMockServerSettings - { - Urls = new[] { url }, - StartAdminInterface = true, - Logger = new WireMockConsoleLogger() - }); - System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(",", server.Urls)); - - server.SetBasicAuthentication("a", "b"); - - server.AllowPartialMapping(); - - server - .Given(Request.Create() - .UsingGet() - .WithHeader("Keep-Alive-Test", "stef") - ) - .RespondWith(Response.Create() - .WithHeader("Keep-Alive", "timeout=1, max=1") - .WithBody("Keep-Alive OK") - ); - - System.Console.WriteLine("Press any key to stop the server"); - System.Console.ReadKey(); - server.Stop(); - - System.Console.WriteLine("Displaying all requests"); - var allRequests = server.LogEntries; - System.Console.WriteLine(JsonConvert.SerializeObject(allRequests, Formatting.Indented)); - - System.Console.WriteLine("Press any key to quit"); - System.Console.ReadKey(); - } - } -} \ No newline at end of file diff --git a/examples/WireMock.Net.Console.HeadersTest/WireMock.Net.Console.HeadersTest.csproj b/examples/WireMock.Net.Console.HeadersTest/WireMock.Net.Console.HeadersTest.csproj deleted file mode 100644 index a6e85cd61..000000000 --- a/examples/WireMock.Net.Console.HeadersTest/WireMock.Net.Console.HeadersTest.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - Exe - netcoreapp1.1 - ../../WireMock.Net-Logo.ico - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - \ No newline at end of file diff --git a/examples/WireMock.Net.Console.HeadersTest/log4net.config b/examples/WireMock.Net.Console.HeadersTest/log4net.config deleted file mode 100644 index feae99529..000000000 --- a/examples/WireMock.Net.Console.HeadersTest/log4net.config +++ /dev/null @@ -1,20 +0,0 @@ - - - -
- - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/WireMock.Net.Console.HeadersTest/nlog.config b/examples/WireMock.Net.Console.HeadersTest/nlog.config deleted file mode 100644 index de6d9072a..000000000 --- a/examples/WireMock.Net.Console.HeadersTest/nlog.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/WireMock.Net/Matchers/JsonMatcher.cs b/src/WireMock.Net/Matchers/JsonMatcher.cs index 4cfff6308..467bd062a 100644 --- a/src/WireMock.Net/Matchers/JsonMatcher.cs +++ b/src/WireMock.Net/Matchers/JsonMatcher.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using System.Linq; +using JetBrains.Annotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using WireMock.Validation; @@ -8,7 +9,7 @@ namespace WireMock.Matchers /// /// JsonMatcher /// - public class JsonMatcher : IValueMatcher + public class JsonMatcher : IValueMatcher, IIgnoreCaseMatcher { /// public object Value { get; } @@ -19,11 +20,15 @@ public class JsonMatcher : IValueMatcher /// public MatchBehaviour MatchBehaviour { get; } + /// + public bool IgnoreCase { get; } + /// /// Initializes a new instance of the class. /// /// The string value to check for equality. - public JsonMatcher([NotNull] string value) : this(MatchBehaviour.AcceptOnMatch, value) + /// Ignore the case from the PropertyName and PropertyValue (string only). + public JsonMatcher([NotNull] string value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) { } @@ -31,7 +36,8 @@ public JsonMatcher([NotNull] string value) : this(MatchBehaviour.AcceptOnMatch, /// Initializes a new instance of the class. /// /// The object value to check for equality. - public JsonMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value) + /// Ignore the case from the PropertyName and PropertyValue (string only). + public JsonMatcher([NotNull] object value, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, value, ignoreCase) { } @@ -40,12 +46,14 @@ public JsonMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, /// /// The match behaviour. /// The string value to check for equality. - public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value) + /// Ignore the case from the PropertyName and PropertyValue (string only). + public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value, bool ignoreCase = false) { Check.NotNull(value, nameof(value)); MatchBehaviour = matchBehaviour; Value = value; + IgnoreCase = ignoreCase; } /// @@ -53,12 +61,14 @@ public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value) /// /// The match behaviour. /// The object value to check for equality. - public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value) + /// Ignore the case from the PropertyName and PropertyValue (string only). + public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false) { Check.NotNull(value, nameof(value)); MatchBehaviour = matchBehaviour; Value = value; + IgnoreCase = ignoreCase; } /// @@ -91,7 +101,7 @@ public double IsMatch(object input) break; } - match = JToken.DeepEquals(jtokenValue, jtokenInput); + match = DeepEquals(jtokenValue, jtokenInput); } catch (JsonException) { @@ -101,5 +111,53 @@ public double IsMatch(object input) return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)); } + + private bool DeepEquals(JToken value, JToken input) + { + if (!IgnoreCase) + { + return JToken.DeepEquals(value, input); + } + + JToken renamedValue = Rename(value); + JToken renamedInput = Rename(input); + + return JToken.DeepEquals(renamedValue, renamedInput); + } + + private static string ToUpper(string input) + { + return input?.ToUpperInvariant(); + } + + // https://stackoverflow.com/questions/11679804/json-net-rename-properties + private static JToken Rename(JToken json) + { + if (json is JProperty property) + { + JToken propertyValue = property.Value; + if (propertyValue.Type == JTokenType.String) + { + string stringValue = propertyValue.Value(); + propertyValue = ToUpper(stringValue); + } + + return new JProperty(ToUpper(property.Name), Rename(propertyValue)); + } + + if (json is JArray array) + { + var renamedValues = array.Select(Rename); + return new JArray(renamedValues); + } + + if (json is JObject obj) + { + var renamedProperties = obj.Properties().Select(Rename); + return new JObject(renamedProperties); + } + + return json; + } } } \ No newline at end of file diff --git a/src/WireMock.Net/Serialization/MatcherMapper.cs b/src/WireMock.Net/Serialization/MatcherMapper.cs index d13931b66..85ec78d21 100644 --- a/src/WireMock.Net/Serialization/MatcherMapper.cs +++ b/src/WireMock.Net/Serialization/MatcherMapper.cs @@ -55,7 +55,7 @@ public IMatcher Map([CanBeNull] MatcherModel matcher) return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true); case "JsonMatcher": - return new JsonMatcher(matchBehaviour, matcher.Pattern); + return new JsonMatcher(matchBehaviour, matcher.Pattern, matcher.IgnoreCase == true); case "JsonPathMatcher": return new JsonPathMatcher(matchBehaviour, stringPatterns); diff --git a/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs b/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs index 0dca72b5f..87ff302a5 100644 --- a/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs +++ b/test/WireMock.Net.Tests/Matchers/JsonMatcherTests.cs @@ -76,7 +76,7 @@ public void JsonMatcher_IsMatch_NullObject() } [Fact] - public void JsonMatcher_IsMatch_JObject1() + public void JsonMatcher_IsMatch_JObject() { // Assign var matcher = new JsonMatcher(new { Id = 1, Name = "Test" }); @@ -94,7 +94,25 @@ public void JsonMatcher_IsMatch_JObject1() } [Fact] - public void JsonMatcher_IsMatch_JObject2() + public void JsonMatcher_IsMatch_WithIgnoreCaseTrue_JObject() + { + // Assign + var matcher = new JsonMatcher(new { id = 1, Name = "test" }, true); + + // Act + var jobject = new JObject + { + { "Id", new JValue(1) }, + { "NaMe", new JValue("Test") } + }; + double match = matcher.IsMatch(jobject); + + // Assert + Assert.Equal(1.0, match); + } + + [Fact] + public void JsonMatcher_IsMatch_JObjectParsed() { // Assign var matcher = new JsonMatcher(new { Id = 1, Name = "Test" }); @@ -107,6 +125,20 @@ public void JsonMatcher_IsMatch_JObject2() Assert.Equal(1.0, match); } + [Fact] + public void JsonMatcher_IsMatch_WithIgnoreCaseTrue_JObjectParsed() + { + // Assign + var matcher = new JsonMatcher(new { Id = 1, Name = "TESt" }, true); + + // Act + var jobject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }"); + double match = matcher.IsMatch(jobject); + + // Assert + Assert.Equal(1.0, match); + } + [Fact] public void JsonMatcher_IsMatch_JObjectAsString() { @@ -125,6 +157,24 @@ public void JsonMatcher_IsMatch_JObjectAsString() Assert.Equal(1.0, match); } + [Fact] + public void JsonMatcher_IsMatch_WithIgnoreCaseTrue_JObjectAsString() + { + // Assign + var matcher = new JsonMatcher("{ \"Id\" : 1, \"Name\" : \"test\" }", true); + + // Act + var jobject = new JObject + { + { "Id", new JValue(1) }, + { "Name", new JValue("Test") } + }; + double match = matcher.IsMatch(jobject); + + // Assert + Assert.Equal(1.0, match); + } + [Fact] public void JsonMatcher_IsMatch_JObjectAsString_RejectOnMatch() {