// Copyright © WireMock.Net using Stef.Validation; using System; using System.Collections.Generic; using System.Linq; namespace WireMock.Matchers.Request; /// /// The request cookie matcher. /// /// public class RequestMessageCookieMatcher : IRequestMatcher { private const string _name = nameof(RequestMessageCookieMatcher); /// /// MatchBehaviour /// public MatchBehaviour MatchBehaviour { get; } /// /// IgnoreCase /// public bool IgnoreCase { get; } /// /// The functions /// public Func, bool>[]? Funcs { get; } /// /// The name /// public string Name { get; } /// /// The matchers. /// public IStringMatcher[]? Matchers { get; } /// /// Initializes a new instance of the class. /// /// The name. /// The pattern. /// Ignore the case from the pattern. /// The match behaviour. public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, string pattern, bool ignoreCase) { MatchBehaviour = matchBehaviour; IgnoreCase = ignoreCase; Name = Guard.NotNull(name); Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, Guard.NotNull(pattern), ignoreCase) }; } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The name. /// The patterns. /// Ignore the case from the pattern. public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, bool ignoreCase, params string[] patterns) : this(matchBehaviour, name, ignoreCase, patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast().ToArray()) { Guard.NotNull(patterns); } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The name. /// The matchers. /// Ignore the case from the pattern. public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, string name, bool ignoreCase, params IStringMatcher[] matchers) { MatchBehaviour = matchBehaviour; Name = Guard.NotNull(name); Matchers = Guard.NotNull(matchers); IgnoreCase = ignoreCase; } /// /// Initializes a new instance of the class. /// /// The funcs. public RequestMessageCookieMatcher(params Func, bool>[] funcs) { Guard.NotNull(funcs); Funcs = funcs; Name = string.Empty; // Not used when Func, but set to a non-null valid value. } /// public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult) { var (score, exception) = GetMatchResult(requestMessage).Expand(); return requestMatchResult.AddScore(GetType(), score, exception); } private MatchResult GetMatchResult(IRequestMessage requestMessage) { if (requestMessage.Cookies == null) { return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch)); } // Check if we want to use IgnoreCase to compare the Cookie-Name and Cookie-Value var cookies = !IgnoreCase ? requestMessage.Cookies : new Dictionary(requestMessage.Cookies, StringComparer.OrdinalIgnoreCase); if (Funcs != null) { return MatchResult.From(_name, MatchScores.ToScore(Funcs.Any(f => f(cookies)))); } if (Matchers == null) { return MatchResult.From(_name); } if (!cookies.ContainsKey(Name)) { return MatchResult.From(_name, MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.Mismatch)); } return MatchResult.From(_name, Matchers.Max(m => m.IsMatch(cookies[Name]))?.Score ?? MatchScores.Mismatch); } }