Add MatchOperator "Or", "And" and "Average" for patterns (#755)

* wip

* ...

* .

* ...

* ...

* path

* url

* b

* t

* client

* .

* RequestMessageMethodMatcherTests

* .

* h

* .

* fix tests

* .
This commit is contained in:
Stef Heyenrath
2022-06-09 21:31:54 +02:00
committed by GitHub
parent 1f23022460
commit 0441c1d85e
95 changed files with 5736 additions and 5111 deletions

View File

@@ -1,19 +1,27 @@
namespace WireMock.Admin.Mappings
namespace WireMock.Admin.Mappings;
/// <summary>
/// Body Model
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class BodyModel
{
/// <summary>
/// Body Model
/// Gets or sets the matcher.
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class BodyModel
{
/// <summary>
/// Gets or sets the matcher.
/// </summary>
public MatcherModel? Matcher { get; set; }
public MatcherModel? Matcher { get; set; }
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public MatcherModel[]? Matchers { get; set; }
}
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public MatcherModel[]? Matchers { get; set; }
/// <summary>
/// The Operator to use when matchers are defined. [Optional]
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
}

View File

@@ -1,14 +1,22 @@
namespace WireMock.Admin.Mappings
namespace WireMock.Admin.Mappings;
/// <summary>
/// ClientIPModel
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class ClientIPModel
{
/// <summary>
/// ClientIPModel
/// Gets or sets the matchers.
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class ClientIPModel
{
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public MatcherModel[] Matchers { get; set; }
}
public MatcherModel[]? Matchers { get; set; }
/// <summary>
/// The Operator to use when matchers are defined. [Optional]
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
}

View File

@@ -1,31 +1,39 @@
using System.Collections.Generic;
namespace WireMock.Admin.Mappings
namespace WireMock.Admin.Mappings;
/// <summary>
/// Header Model
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class HeaderModel
{
/// <summary>
/// Header Model
/// Gets or sets the name.
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class HeaderModel
{
/// <summary>
/// Gets or sets the name.
/// </summary>
public string Name { get; set; } = null!;
public string Name { get; set; } = null!;
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public IList<MatcherModel>? Matchers { get; set; }
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public IList<MatcherModel>? Matchers { get; set; }
/// <summary>
/// Gets or sets the ignore case.
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Gets or sets the ignore case.
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
}
/// <summary>
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
/// <summary>
/// The Operator to use when matchers are defined. [Optional]
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
}

View File

@@ -1,78 +1,77 @@
using System;
using WireMock.Models;
namespace WireMock.Admin.Mappings
namespace WireMock.Admin.Mappings;
/// <summary>
/// MappingModel
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class MappingModel
{
/// <summary>
/// MappingModel
/// Gets or sets the unique identifier.
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class MappingModel
{
/// <summary>
/// Gets or sets the unique identifier.
/// </summary>
public Guid? Guid { get; set; }
public Guid? Guid { get; set; }
/// <summary>
/// Gets or sets the TimeSettings when which this mapping should be used.
/// </summary>
public TimeSettingsModel TimeSettings { get; set; }
/// <summary>
/// Gets or sets the TimeSettings when which this mapping should be used.
/// </summary>
public TimeSettingsModel? TimeSettings { get; set; }
/// <summary>
/// The unique title.
/// </summary>
public string Title { get; set; }
/// <summary>
/// The unique title.
/// </summary>
public string? Title { get; set; }
/// <summary>
/// The description.
/// </summary>
public string Description { get; set; }
/// <summary>
/// The description.
/// </summary>
public string? Description { get; set; }
/// <summary>
/// The priority. (A low value means higher priority.)
/// </summary>
public int? Priority { get; set; }
/// <summary>
/// The priority. (A low value means higher priority.)
/// </summary>
public int? Priority { get; set; }
/// <summary>
/// The Scenario.
/// </summary>
public string Scenario { get; set; }
/// <summary>
/// The Scenario.
/// </summary>
public string? Scenario { get; set; }
/// <summary>
/// Execution state condition for the current mapping.
/// </summary>
public string WhenStateIs { get; set; }
/// <summary>
/// Execution state condition for the current mapping.
/// </summary>
public string? WhenStateIs { get; set; }
/// <summary>
/// The next state which will be signaled after the current mapping execution.
/// In case the value is null state will not be changed.
/// </summary>
public string SetStateTo { get; set; }
/// <summary>
/// The next state which will be signaled after the current mapping execution.
/// In case the value is null state will not be changed.
/// </summary>
public string? SetStateTo { get; set; }
/// <summary>
/// The request model.
/// </summary>
public RequestModel Request { get; set; }
/// <summary>
/// The request model.
/// </summary>
public RequestModel Request { get; set; }
/// <summary>
/// The response model.
/// </summary>
public ResponseModel Response { get; set; }
/// <summary>
/// The response model.
/// </summary>
public ResponseModel Response { get; set; }
/// <summary>
/// Saves this mapping as a static mapping file.
/// </summary>
public bool? SaveToFile { get; set; }
/// <summary>
/// Saves this mapping as a static mapping file.
/// </summary>
public bool? SaveToFile { get; set; }
/// <summary>
/// The Webhook.
/// </summary>
public WebhookModel Webhook { get; set; }
/// <summary>
/// The Webhook.
/// </summary>
public WebhookModel? Webhook { get; set; }
/// <summary>
/// The Webhooks.
/// </summary>
public WebhookModel[] Webhooks { get; set; }
}
/// <summary>
/// The Webhooks.
/// </summary>
public WebhookModel[]? Webhooks { get; set; }
}

View File

@@ -35,5 +35,14 @@ namespace WireMock.Admin.Mappings
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
/// <summary>
/// The Operator to use when multiple patterns are defined. Optional.
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
}
}

View File

@@ -1,14 +1,22 @@
namespace WireMock.Admin.Mappings
namespace WireMock.Admin.Mappings;
/// <summary>
/// PathModel
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class PathModel
{
/// <summary>
/// PathModel
/// Gets or sets the matchers.
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class PathModel
{
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public MatcherModel[]? Matchers { get; set; }
}
public MatcherModel[]? Matchers { get; set; }
/// <summary>
/// The Operator to use when matchers are defined. [Optional]
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
}

View File

@@ -28,6 +28,20 @@ public class RequestModel
/// </summary>
public string[]? Methods { get; set; }
/// <summary>
/// Reject on match for Methods.
/// </summary>
public bool? MethodsRejectOnMatch { get; set; }
/// <summary>
/// The Operator to use when Methods are defined. [Optional]
/// - null = Same as "or".
/// - "or" = Only one method should match.
/// - "and" = All methods should match.
/// - "average" = The average value from all methods.
/// </summary>
public string? MethodsMatchOperator { get; set; }
/// <summary>
/// Gets or sets the Headers.
/// </summary>

View File

@@ -1,14 +1,22 @@
namespace WireMock.Admin.Mappings
namespace WireMock.Admin.Mappings;
/// <summary>
/// UrlModel
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class UrlModel
{
/// <summary>
/// UrlModel
/// Gets or sets the matchers.
/// </summary>
[FluentBuilder.AutoGenerateBuilder]
public class UrlModel
{
/// <summary>
/// Gets or sets the matchers.
/// </summary>
public MatcherModel[] Matchers { get; set; }
}
}
public MatcherModel[]? Matchers { get; set; }
/// <summary>
/// The Operator to use when matchers are defined. [Optional]
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
}

View File

@@ -3,136 +3,135 @@ using System.Collections.Generic;
using WireMock.Types;
using WireMock.Util;
namespace WireMock
namespace WireMock;
/// <summary>
/// IRequestMessage
/// </summary>
public interface IRequestMessage
{
/// <summary>
/// IRequestMessage
/// Gets the Client IP Address.
/// </summary>
public interface IRequestMessage
{
/// <summary>
/// Gets the Client IP Address.
/// </summary>
string ClientIP { get; }
string ClientIP { get; }
/// <summary>
/// Gets the url (relative).
/// </summary>
string Url { get; }
/// <summary>
/// Gets the url (relative).
/// </summary>
string Url { get; }
/// <summary>
/// Gets the AbsoluteUrl.
/// </summary>
string AbsoluteUrl { get; }
/// <summary>
/// Gets the AbsoluteUrl.
/// </summary>
string AbsoluteUrl { get; }
/// <summary>
/// The ProxyUrl (if a proxy is used).
/// </summary>
string ProxyUrl { get; set; }
/// <summary>
/// The ProxyUrl (if a proxy is used).
/// </summary>
string ProxyUrl { get; set; }
/// <summary>
/// Gets the DateTime.
/// </summary>
DateTime DateTime { get; }
/// <summary>
/// Gets the DateTime.
/// </summary>
DateTime DateTime { get; }
/// <summary>
/// Gets the path (relative).
/// </summary>
string Path { get; }
/// <summary>
/// Gets the path (relative).
/// </summary>
string Path { get; }
/// <summary>
/// Gets the AbsolutePath.
/// </summary>
string AbsolutePath { get; }
/// <summary>
/// Gets the AbsolutePath.
/// </summary>
string AbsolutePath { get; }
/// <summary>
/// Gets the path segments.
/// </summary>
string[] PathSegments { get; }
/// <summary>
/// Gets the path segments.
/// </summary>
string[] PathSegments { get; }
/// <summary>
/// Gets the absolute path segments.
/// </summary>
string[] AbsolutePathSegments { get; }
/// <summary>
/// Gets the absolute path segments.
/// </summary>
string[] AbsolutePathSegments { get; }
/// <summary>
/// Gets the method.
/// </summary>
string Method { get; }
/// <summary>
/// Gets the method.
/// </summary>
string Method { get; }
/// <summary>
/// Gets the headers.
/// </summary>
IDictionary<string, WireMockList<string>> Headers { get; }
/// <summary>
/// Gets the headers.
/// </summary>
IDictionary<string, WireMockList<string>>? Headers { get; }
/// <summary>
/// Gets the cookies.
/// </summary>
IDictionary<string, string> Cookies { get; }
/// <summary>
/// Gets the cookies.
/// </summary>
IDictionary<string, string>? Cookies { get; }
/// <summary>
/// Gets the query.
/// </summary>
IDictionary<string, WireMockList<string>> Query { get; }
/// <summary>
/// Gets the query.
/// </summary>
IDictionary<string, WireMockList<string>>? Query { get; }
/// <summary>
/// Gets the raw query.
/// </summary>
string RawQuery { get; }
/// <summary>
/// Gets the raw query.
/// </summary>
string RawQuery { get; }
/// <summary>
/// The body.
/// </summary>
IBodyData? BodyData { get; }
/// <summary>
/// The body.
/// </summary>
IBodyData? BodyData { get; }
/// <summary>
/// The original body as string. Convenience getter for Handlebars.
/// </summary>
string Body { get; }
/// <summary>
/// The original body as string. Convenience getter for Handlebars.
/// </summary>
string Body { get; }
/// <summary>
/// The body (as JSON object). Convenience getter for Handlebars.
/// </summary>
object BodyAsJson { get; }
/// <summary>
/// The body (as JSON object). Convenience getter for Handlebars.
/// </summary>
object BodyAsJson { get; }
/// <summary>
/// The body (as bytearray). Convenience getter for Handlebars.
/// </summary>
byte[] BodyAsBytes { get; }
/// <summary>
/// The body (as bytearray). Convenience getter for Handlebars.
/// </summary>
byte[] BodyAsBytes { get; }
/// <summary>
/// The detected body type. Convenience getter for Handlebars.
/// </summary>
string DetectedBodyType { get; }
/// <summary>
/// The detected body type. Convenience getter for Handlebars.
/// </summary>
string DetectedBodyType { get; }
/// <summary>
/// The detected body type from the Content-Type header. Convenience getter for Handlebars.
/// </summary>
string DetectedBodyTypeFromContentType { get; }
/// <summary>
/// The detected body type from the Content-Type header. Convenience getter for Handlebars.
/// </summary>
string DetectedBodyTypeFromContentType { get; }
/// <summary>
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
/// </summary>
string DetectedCompression { get; }
/// <summary>
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
/// </summary>
string DetectedCompression { get; }
/// <summary>
/// Gets the Host
/// </summary>
string Host { get; }
/// <summary>
/// Gets the Host
/// </summary>
string Host { get; }
/// <summary>
/// Gets the protocol
/// </summary>
string Protocol { get; }
/// <summary>
/// Gets the protocol
/// </summary>
string Protocol { get; }
/// <summary>
/// Gets the port
/// </summary>
int Port { get; }
/// <summary>
/// Gets the port
/// </summary>
int Port { get; }
/// <summary>
/// Gets the origin
/// </summary>
string Origin { get; }
}
/// <summary>
/// Gets the origin
/// </summary>
string Origin { get; }
}

View File

@@ -38,7 +38,7 @@ namespace WireMock
/// <summary>
/// Gets the headers.
/// </summary>
IDictionary<string, WireMockList<string>> Headers { get; }
IDictionary<string, WireMockList<string>>? Headers { get; }
/// <summary>
/// Gets or sets the status code.

View File

@@ -15,6 +15,6 @@ namespace WireMock.Matchers.Request
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
double GetMatchingScore([NotNull] IRequestMessage requestMessage, [NotNull] IRequestMatchResult requestMatchResult);
double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult);
}
}

View File

@@ -22,12 +22,12 @@ namespace WireMock.Models
/// <summary>
/// The Headers to send.
/// </summary>
IDictionary<string, WireMockList<string>> Headers { get; }
IDictionary<string, WireMockList<string>>? Headers { get; }
/// <summary>
/// The body to send.
/// </summary>
IBodyData BodyData { get; set; }
IBodyData? BodyData { get; set; }
/// <summary>
/// Use Transformer.