#pragma warning disable CS1591 using System; using System.Collections.Generic; using AnyOfTypes; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using WireMock.Extensions; using WireMock.Matchers; using WireMock.Models; // ReSharper disable once CheckNamespace namespace WireMock.FluentAssertions; public partial class WireMockAssertions { private const string MessageFormatNoCalls = "Expected {context:wiremockserver} to have been called using body {0}{reason}, but no calls were made."; private const string MessageFormat = "Expected {context:wiremockserver} to have been called using body {0}{reason}, but didn't find it among the body/bodies {1}."; [CustomAssertion] public AndConstraint WithBody(string body, string because = "", params object[] becauseArgs) { return WithBody(new WildcardMatcher(body), because, becauseArgs); } [CustomAssertion] public AndConstraint WithBodyAsJson(object body, string because = "", params object[] becauseArgs) { return WithBodyAsJson(new JsonMatcher(body), because, becauseArgs); } [CustomAssertion] public AndConstraint WithBodyAsJson(string body, string because = "", params object[] becauseArgs) { return WithBodyAsJson(new JsonMatcher(body), because, becauseArgs); } [CustomAssertion] public AndConstraint WithBodyAsBytes(byte[] body, string because = "", params object[] becauseArgs) { return WithBodyAsBytes(new ExactObjectMatcher(body), because, becauseArgs); } [CustomAssertion] public AndConstraint WithBody(IStringMatcher matcher, string because = "", params object[] becauseArgs) { var (filter, condition) = BuildFilterAndCondition(r => r.Body, matcher); return ExecuteAssertionWithBodyStringMatcher(matcher, because, becauseArgs, condition, filter, r => r.Body); } [CustomAssertion] public AndConstraint WithBodyAsJson(IObjectMatcher matcher, string because = "", params object[] becauseArgs) { var (filter, condition) = BuildFilterAndCondition(r => r.BodyAsJson, matcher); return ExecuteAssertionWithBodyAsIObjectMatcher(matcher, because, becauseArgs, condition, filter, r => r.BodyAsJson); } [CustomAssertion] public AndConstraint WithBodyAsBytes(ExactObjectMatcher matcher, string because = "", params object[] becauseArgs) { var (filter, condition) = BuildFilterAndCondition(r => r.BodyAsBytes, matcher); return ExecuteAssertionWithBodyAsIObjectMatcher(matcher, because, becauseArgs, condition, filter, r => r.BodyAsBytes); } private AndConstraint ExecuteAssertionWithBodyStringMatcher( IStringMatcher matcher, string because, object[] becauseArgs, Func, bool> condition, Func, IReadOnlyList> filter, Func expression ) { Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => RequestMessages) .ForCondition(requests => CallsCount == 0 || requests.Any()) .FailWith( MessageFormatNoCalls, FormatBody(matcher.GetPatterns()) ) .Then .ForCondition(condition) .FailWith( MessageFormat, _ => FormatBody(matcher.GetPatterns()), requests => FormatBodies(requests.Select(expression)) ); FilterRequestMessages(filter); return new AndConstraint(this); } private AndConstraint ExecuteAssertionWithBodyAsIObjectMatcher( IObjectMatcher matcher, string because, object[] becauseArgs, Func, bool> condition, Func, IReadOnlyList> filter, Func expression ) { Execute.Assertion .BecauseOf(because, becauseArgs) .Given(() => RequestMessages) .ForCondition(requests => CallsCount == 0 || requests.Any()) .FailWith( MessageFormatNoCalls, FormatBody(matcher.Value) ) .Then .ForCondition(condition) .FailWith( MessageFormat, _ => FormatBody(matcher.Value), requests => FormatBodies(requests.Select(expression)) ); FilterRequestMessages(filter); return new AndConstraint(this); } private static string? FormatBody(object? body) { return body switch { null => null, string str => str, AnyOf[] stringPatterns => FormatBodies(stringPatterns.Select(p => p.GetPattern())), byte[] bytes => $"byte[{bytes.Length}] {{...}}", JToken jToken => jToken.ToString(Formatting.None), _ => JToken.FromObject(body).ToString(Formatting.None) }; } private static string? FormatBodies(IEnumerable bodies) { var valueAsArray = bodies as object[] ?? bodies.ToArray(); return valueAsArray.Length == 1 ? FormatBody(valueAsArray.First()) : $"[ {string.Join(", ", valueAsArray.Select(FormatBody))} ]"; } }