Compare commits

...

20 Commits

Author SHA1 Message Date
Stef Heyenrath
ce2db748f1 1.0.4.0 2018-06-23 11:26:24 +02:00
Stef Heyenrath
443fc76773 Add request / response logging (#151)
Add request / response logging (#151)
2018-06-23 11:22:07 +02:00
Stef Heyenrath
454051568a 1.0.3.20 2018-05-29 22:01:15 +02:00
Stef Heyenrath
2b498f45cb Revert PortUtil.cs changes (#147) 2018-05-29 21:58:56 +02:00
Stef Heyenrath
2fcfda49c7 Update changelog 2018-05-28 15:13:34 +02:00
Stef Heyenrath
7ef0c1d68b 1.0.3.19 2018-05-28 08:43:41 +02:00
Bob Paul
297743a19a Fix code for .NET Core 2 so that server has cancellation token, and Stop method waits for shutdown. This resolves issues when using .NET Core 2 and starting/stopping server instances. (#145) 2018-05-28 08:30:18 +02:00
Stef Heyenrath
0640c88bcd Fix ConcurrentDictionary (#129) (#144) 2018-05-28 08:08:18 +02:00
Stef Heyenrath
dc39f91205 1.0.3.18 2018-05-25 21:43:29 +02:00
Stef Heyenrath
eda71bd725 Allow all headers to be set as Response headers (#142)
* Allow all headers to be set as Response headers

* RunTestDifferentPort

* Fix Proxy_Should_change_absolute_location_header_in_proxied_response test

* Fix OwinResponseMapper

* Fix test

* 1.0.3.18
2018-05-25 21:04:58 +02:00
Stef Heyenrath
538d04e440 Changelog for 1.0.3.17 2018-05-16 22:30:25 +02:00
Alastair Crabtree
c575ca8296 Merge pull request #138 from WireMock-Net/stef_negate_matcher
Added Negate matcher logic
2018-05-16 20:19:48 +01:00
Stef Heyenrath
d0e76b3dbe Merge into the stef_negate_matcher branch (solves issue #133) (#135)
* Fixed #133

* tests: add parametrised tests that cover various body matchers for json

* Code review comments (BodyAsStringOriginal)

* tests: minor method name change
2018-05-15 12:41:07 +02:00
Alastair Crabtree
a8ddd31c9c Stef negate matcher (#134)
* RejectOnMatch (wip)

* RejectOnMatch (wip)

* RejectOnMatch (wip)

* RejectOnMatch (wip)

* docs: improve sample app matcher to show use of reject on match

* Reworked code review comments
2018-05-12 12:51:56 +02:00
Stef Heyenrath
d3640d065e Reworked code review comments 2018-05-12 12:45:58 +02:00
Alastair Crabtree
9d6df1c7c8 docs: improve sample app matcher to show use of reject on match 2018-05-12 01:19:01 +01:00
Stef Heyenrath
ca5056aed3 RejectOnMatch (wip) 2018-05-06 10:40:42 +02:00
Stef Heyenrath
e7319a202a RejectOnMatch (wip) 2018-05-04 20:27:39 +02:00
Stef Heyenrath
8959e55ca3 RejectOnMatch (wip) 2018-05-04 08:16:42 +02:00
Stef Heyenrath
0fb4b62b50 RejectOnMatch (wip) 2018-05-03 16:59:31 +02:00
74 changed files with 1583 additions and 700 deletions

View File

@@ -1,3 +1,59 @@
# 1.0.4.0 (23 June 2018)
- [#151](https://github.com/WireMock-Net/WireMock.Net/issues/151) - Feature: Add logging of incoming request and body for tracability
- [#149](https://github.com/WireMock-Net/WireMock.Net/issues/149) - Question: Transformer and Delay in Static Mappings?
- [#131](https://github.com/WireMock-Net/WireMock.Net/issues/131) - Bug: CurlException Couldn't connect to Server when running multiple tests
Commits: 443fc76773...443fc76773
# 1.0.3.20 (29 May 2018)
- [#147](https://github.com/WireMock-Net/WireMock.Net/pull/147) - Revert PortUtil.cs changes contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#146](https://github.com/WireMock-Net/WireMock.Net/issues/146) - Hang possibly due to Windows firewall prompt
- [#129](https://github.com/WireMock-Net/WireMock.Net/issues/129) - Random test failures between WireMock.Net 1.0.3.1 and 1.0.3.2
Commits: 2fcfda49c7...2b498f45cb
# 1.0.3.19 (28 May 2018)
- [#129](https://github.com/WireMock-Net/WireMock.Net/issues/129) - Random test failures between WireMock.Net 1.0.3.1 and 1.0.3.2
- [#145](https://github.com/WireMock-Net/WireMock.Net/pull/145) - Cancellation token not passed to server instance in .NET Core 2 contributed by Bob Paul ([Bob11327](https://github.com/Bob11327)) +fix
- [#144](https://github.com/WireMock-Net/WireMock.Net/pull/144) - Fix ConcurrentDictionary (#129) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
Commits: ...
# 1.0.3.18 (25 May 2018)
- [#142](https://github.com/WireMock-Net/WireMock.Net/pull/142) - Allow all headers to be set as Response headers contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#140](https://github.com/WireMock-Net/WireMock.Net/issues/140) - Question: Why the Microsoft.Owin.Host.HttpListener is not referenced in the dll, which uses WireMock?
- [#139](https://github.com/WireMock-Net/WireMock.Net/issues/139) - Wiki link https://github.com/StefH/WireMock.Net/wiki/Record-(via-proxy)-and-Save is dead
- [#137](https://github.com/WireMock-Net/WireMock.Net/issues/137) - Question: How to specify Transfer-Encoding response header?
- [#136](https://github.com/WireMock-Net/WireMock.Net/issues/136) - Question: Does the WireMock send Content-Length response header
- [#132](https://github.com/WireMock-Net/WireMock.Net/issues/132) - LogEntries not being recorded on subsequent tests
- [#127](https://github.com/WireMock-Net/WireMock.Net/issues/127) - Question: Stub priority - Most recent stub is not always used
- [#126](https://github.com/WireMock-Net/WireMock.Net/issues/126) - Question: UsingHead always returns 0 for Content-Length header even when explicitly specified
- [#122](https://github.com/WireMock-Net/WireMock.Net/issues/122) - WireMock.Net not responding in unit tests - same works in console application
- [#97](https://github.com/WireMock-Net/WireMock.Net/issues/97) - Request matching logic is not practical
Commits: eda71bd725...eda71bd725
# 1.0.3.17 (16 May 2018)
- [#138](https://github.com/WireMock-Net/WireMock.Net/pull/138) - Added Negate matcher logic contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#135](https://github.com/WireMock-Net/WireMock.Net/pull/135) - Merge into the stef_negate_matcher branch (solves issue #133) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#134](https://github.com/WireMock-Net/WireMock.Net/pull/134) - Stef negate matcher contributed by Alastair Crabtree ([alastairtree](https://github.com/alastairtree))
- [#133](https://github.com/WireMock-Net/WireMock.Net/issues/133) - Issue: Wildcard matching a json body does not work? +fix
- [#128](https://github.com/WireMock-Net/WireMock.Net/issues/128) - Feature: Negate a matcher +feature
- [#126](https://github.com/WireMock-Net/WireMock.Net/issues/126) - Question: UsingHead always returns 0 for Content-Length header even when explicitly specified
- [#103](https://github.com/WireMock-Net/WireMock.Net/issues/103) - Support for Faults
Commits: 0fb4b62b50...c575ca8296
# 1.0.3.16 (15 April 2018)
- [#125](https://github.com/WireMock-Net/WireMock.Net/pull/125) - Change listen from loopback to any ip address for dotnetcore2.0 apps contributed by ([SubjectiveReality](https://github.com/SubjectiveReality))

View File

@@ -1,5 +1,5 @@
https://github.com/GitTools/GitReleaseNotes
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.3.16
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.4.0
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags

View File

@@ -1,4 +1,10 @@
using Newtonsoft.Json;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
@@ -8,6 +14,9 @@ namespace WireMock.Net.Console.Proxy.NETCoreApp2
{
static void Main(string[] args)
{
RunTestDifferentPort().Wait(20000); // prints "1"
RunTestDifferentPort().Wait(20000); // prints "1"
var server = FluentMockServer.Start(new FluentMockServerSettings
{
Urls = new[] { "http://localhost:9091", "https://localhost:9443" },
@@ -32,5 +41,22 @@ namespace WireMock.Net.Console.Proxy.NETCoreApp2
System.Console.ReadKey();
server.Stop();
}
private static async Task RunTestDifferentPort()
{
var server = FluentMockServer.Start();
server.Given(Request.Create().WithPath("/").UsingGet())
.RespondWith(Response.Create().WithStatusCode(200).WithBody("Hello"));
Thread.Sleep(1000);
var response = await new HttpClient().GetAsync(server.Urls[0]);
response.EnsureSuccessStatusCode();
System.Console.WriteLine("RunTestDifferentPort - server.LogEntries.Count() = " + server.LogEntries.Count());
server.Stop();
}
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Net;
using Newtonsoft.Json;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
@@ -27,7 +29,8 @@ namespace WireMock.Net.ConsoleApplication
// SaveMapping = true
//},
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); }
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); },
Logger = new WireMockConsoleLogger()
});
System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(",", server.Urls));
@@ -150,6 +153,28 @@ namespace WireMock.Net.ConsoleApplication
.WithHeader("Content-Type", "application/json")
.WithBody(@"{ ""result"": ""data deleted with 200""}"));
server
.Given(Request.Create()
.WithPath("/needs-a-key")
.UsingGet()
.WithHeader("api-key", "*", MatchBehaviour.AcceptOnMatch)
.UsingAnyMethod())
.RespondWith(Response.Create()
.WithStatusCode(HttpStatusCode.OK)
.WithBody(@"{ ""result"": ""api-key found""}"));
server
.Given(Request.Create()
.WithPath("/needs-a-key")
.UsingGet()
.WithHeader("api-key", "*", MatchBehaviour.RejectOnMatch)
.UsingAnyMethod())
.RespondWith(Response.Create()
.WithStatusCode(HttpStatusCode.Unauthorized)
.WithBody(@"{ ""result"": ""api-key missing""}"));
server
.Given(Request.Create().WithPath("/nobody").UsingGet())
.RespondWith(Response.Create().WithDelay(TimeSpan.FromSeconds(1))

View File

@@ -1,4 +1,6 @@
using log4net;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
using WireMock.Logging;
namespace WireMock.Net.StandAlone.NETCoreApp
@@ -26,5 +28,11 @@ namespace WireMock.Net.StandAlone.NETCoreApp
{
Log.ErrorFormat(formatString, args);
}
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
Log.DebugFormat("Admin[{0}] {1}", isAdminRequest, message);
}
}
}

View File

@@ -1,6 +1,7 @@
using System.Threading;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
using WireMock.Logging;
using WireMock.Net.StandAlone;
using WireMock.Settings;
@@ -42,6 +43,12 @@ namespace WireMock.Net.WebApplication
{
_logger.LogError(formatString, args);
}
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminrequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
_logger.LogDebug("Admin[{0}] {1}", isAdminrequest, message);
}
}
public WireMockService(ILogger logger, IFluentMockServerSettings settings)

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Version>1.0.3.16</Version>
<Version>1.0.4.0</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

View File

@@ -24,5 +24,10 @@
/// Gets or sets the ignore case.
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
@@ -43,5 +44,13 @@ namespace WireMock.Logging
[PublicAPI]
[StringFormatMethod("formatString")]
void Error([NotNull] string formatString, [NotNull] params object[] args);
/// <summary>
/// Writes the LogEntryModel (LogRequestModel, LogResponseModel and more).
/// </summary>
/// <param name="logEntryModel">The Request Log Model.</param>
/// <param name="isAdminrequest">Defines if this request is an admin request.</param>
[PublicAPI]
void DebugRequestResponse([NotNull] LogEntryModel logEntryModel, bool isAdminrequest);
}
}

View File

@@ -1,4 +1,6 @@
using System;
using Newtonsoft.Json;
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
@@ -8,6 +10,14 @@ namespace WireMock.Logging
/// <seealso cref="IWireMockLogger" />
public class WireMockConsoleLogger : IWireMockLogger
{
/// <summary>
/// Initializes a new instance of the <see cref="WireMockConsoleLogger"/> class.
/// </summary>
public WireMockConsoleLogger()
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
}
/// <see cref="IWireMockLogger.Debug"/>
public void Debug(string formatString, params object[] args)
{
@@ -32,9 +42,16 @@ namespace WireMock.Logging
Console.WriteLine(Format("Error", formatString, args));
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
Console.WriteLine(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
}
private static string Format(string level, string formatString, params object[] args)
{
string message = string.Format(formatString, args);
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
return $"{DateTime.UtcNow} [{level}] : {message}";
}

View File

@@ -1,4 +1,6 @@
namespace WireMock.Logging
using WireMock.Admin.Requests;
namespace WireMock.Logging
{
/// <summary>
/// WireMockNullLogger which does not log.
@@ -25,5 +27,10 @@
public void Error(string formatString, params object[] args)
{
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
}
}
}

View File

@@ -12,21 +12,34 @@ namespace WireMock.Matchers
{
private readonly string[] _values;
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="values">The values.</param>
public ExactMatcher([NotNull] params string[] values)
public ExactMatcher([NotNull] params string[] values) : this(MatchBehaviour.AcceptOnMatch, values)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="values">The values.</param>
public ExactMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] values)
{
Check.HasNoNulls(values, nameof(values));
_values = values;
MatchBehaviour = matchBehaviour;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
return MatchScores.ToScore(_values.Select(value => value.Equals(input)));
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_values.Select(value => value.Equals(input))));
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
@@ -35,10 +48,7 @@ namespace WireMock.Matchers
return _values;
}
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "ExactMatcher";
}
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "ExactMatcher";
}
}

View File

@@ -1,5 +1,6 @@
using System.Linq;
using JetBrains.Annotations;
using WireMock.Validation;
namespace WireMock.Matchers
{
@@ -12,35 +13,59 @@ namespace WireMock.Matchers
private readonly object _object;
private readonly byte[] _bytes;
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="value">The value.</param>
public ExactObjectMatcher([NotNull] object value)
public ExactObjectMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value.</param>
public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
{
Check.NotNull(value, nameof(value));
_object = value;
MatchBehaviour = matchBehaviour;
}
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="value">The value.</param>
public ExactObjectMatcher([NotNull] byte[] value)
public ExactObjectMatcher([NotNull] byte[] value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value.</param>
public ExactObjectMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] value)
{
Check.NotNull(value, nameof(value));
_bytes = value;
MatchBehaviour = matchBehaviour;
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
{
bool equals = _object != null ? Equals(_object, input) : _bytes.SequenceEqual((byte[])input);
return MatchScores.ToScore(equals);
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(equals));
}
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "ExactObjectMatcher";
}
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "ExactObjectMatcher";
}
}

View File

@@ -3,10 +3,11 @@
/// <summary>
/// IIgnoreCaseMatcher
/// </summary>
/// <inheritdoc cref="IMatcher"/>
public interface IIgnoreCaseMatcher : IMatcher
{
/// <summary>
/// Ignore the case.
/// Ignore the case from the pattern.
/// </summary>
bool IgnoreCase { get; }
}

View File

@@ -8,7 +8,12 @@
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>Name</returns>
string GetName();
string Name { get; }
/// <summary>
/// Gets the match behaviour.
/// </summary>
MatchBehaviour MatchBehaviour { get; }
}
}

View File

@@ -3,6 +3,7 @@
/// <summary>
/// IStringMatcher
/// </summary>
/// <inheritdoc cref="IMatcher"/>
public interface IStringMatcher : IMatcher
{
/// <summary>

View File

@@ -1,6 +1,6 @@
using System;
using System.Linq;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Validation;
@@ -14,54 +14,69 @@ namespace WireMock.Matchers
{
private readonly string[] _patterns;
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary>
/// <param name="patterns">The patterns.</param>
public JsonPathMatcher([NotNull] params string[] patterns)
public JsonPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonPathMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param>
public JsonPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns)
{
Check.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour;
_patterns = patterns;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
if (input == null)
double match = MatchScores.Mismatch;
if (input != null)
{
return MatchScores.Mismatch;
try
{
var jtoken = JToken.Parse(input);
match = IsMatch(jtoken);
}
catch (JsonException)
{
// just ignore JsonException
}
}
try
{
var jtoken = JToken.Parse(input);
return IsMatch(jtoken);
}
catch (Exception)
{
return MatchScores.Mismatch;
}
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
{
if (input == null)
double match = MatchScores.Mismatch;
if (input != null)
{
return MatchScores.Mismatch;
try
{
// Check if JToken or object
JToken jtoken = input is JToken token ? token : JObject.FromObject(input);
match = IsMatch(jtoken);
}
catch (JsonException)
{
// just ignore JsonException
}
}
try
{
// Check if JToken or object
JToken jtoken = input is JToken token ? token : JObject.FromObject(input);
return IsMatch(jtoken);
}
catch (Exception)
{
return MatchScores.Mismatch;
}
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
@@ -70,11 +85,8 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "JsonPathMatcher";
}
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "JsonPathMatcher";
private double IsMatch(JToken jtoken)
{

View File

@@ -0,0 +1,18 @@
namespace WireMock.Matchers
{
/// <summary>
/// MatchBehaviour
/// </summary>
public enum MatchBehaviour
{
/// <summary>
/// Accept on match (default)
/// </summary>
AcceptOnMatch,
/// <summary>
/// Reject on match
/// </summary>
RejectOnMatch
}
}

View File

@@ -0,0 +1,28 @@
namespace WireMock.Matchers
{
internal static class MatchBehaviourHelper
{
/// <summary>
/// Converts the specified match behaviour and match value to a new match value.
///
/// if AcceptOnMatch --> return match (default)
/// if RejectOnMatch and match = 0.0 --> return 1.0
/// if RejectOnMatch and match = 0.? --> return 0.0
/// if RejectOnMatch and match = 1.0 --> return 0.0
/// </summary>
///
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="match">The match.</param>
/// <returns>match value</returns>
internal static double Convert(MatchBehaviour matchBehaviour, double match)
{
if (matchBehaviour == MatchBehaviour.AcceptOnMatch)
{
return match;
}
return match <= MatchScores.Tolerance ? MatchScores.Perfect : MatchScores.Mismatch;
}
}
}

View File

@@ -9,18 +9,32 @@ namespace WireMock.Matchers
/// <summary>
/// Regular Expression Matcher
/// </summary>
/// <seealso cref="IStringMatcher" />
/// <inheritdoc cref="IStringMatcher"/>
/// <inheritdoc cref="IIgnoreCaseMatcher"/>
public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
{
private readonly string[] _patterns;
private readonly Regex[] _expressions;
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase</param>
public RegexMatcher([NotNull, RegexPattern] string pattern, bool ignoreCase = false) : this(new [] { pattern }, ignoreCase )
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RegexMatcher([NotNull, RegexPattern] string pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] string pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
{
}
@@ -28,13 +42,24 @@ namespace WireMock.Matchers
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">IgnoreCase</param>
public RegexMatcher([NotNull, RegexPattern] string[] patterns, bool ignoreCase = false)
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RegexMatcher([NotNull, RegexPattern] string[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RegexMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
public RegexMatcher(MatchBehaviour matchBehaviour, [NotNull, RegexPattern] string[] patterns, bool ignoreCase = false)
{
Check.NotNull(patterns, nameof(patterns));
_patterns = patterns;
IgnoreCase = ignoreCase;
MatchBehaviour = matchBehaviour;
RegexOptions options = RegexOptions.Compiled;
if (ignoreCase)
@@ -48,19 +73,20 @@ namespace WireMock.Matchers
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
if (input == null)
double match = MatchScores.Mismatch;
if (input != null)
{
return MatchScores.Mismatch;
}
try
{
return MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)));
}
catch (Exception)
{
return MatchScores.Mismatch;
try
{
match = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)));
}
catch (Exception)
{
// just ignore exception
}
}
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
@@ -69,11 +95,8 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc cref="IMatcher.GetName"/>
public virtual string GetName()
{
return "RegexMatcher";
}
/// <inheritdoc cref="IMatcher.Name"/>
public virtual string Name => "RegexMatcher";
/// <inheritdoc cref="IIgnoreCaseMatcher.IgnoreCase"/>
public bool IgnoreCase { get; }

View File

@@ -32,24 +32,27 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="body">The body.</param>
public RequestMessageBodyMatcher([NotNull] string body) : this(new SimMetricsMatcher(body))
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] string body) : this(new WildcardMatcher(matchBehaviour, body))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="body">The body.</param>
public RequestMessageBodyMatcher([NotNull] byte[] body) : this(new ExactObjectMatcher(body))
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] body) : this(new ExactObjectMatcher(matchBehaviour, body))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="body">The body.</param>
public RequestMessageBodyMatcher([NotNull] object body) : this(new ExactObjectMatcher(body))
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] object body) : this(new ExactObjectMatcher(matchBehaviour, body))
{
}
@@ -102,27 +105,38 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (requestMessage.Body != null)
{
if (Matcher is IStringMatcher stringMatcher)
{
return stringMatcher.IsMatch(requestMessage.Body);
}
}
// Check if the matcher is a IObjectMatcher
if (Matcher is IObjectMatcher objectMatcher)
{
// If the body is a JSON object, try to match.
if (requestMessage.BodyAsJson != null)
{
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
}
// If the body is a byte array, try to match.
if (requestMessage.BodyAsBytes != null)
{
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
}
}
// Check if the matcher is a IStringMatcher
if (Matcher is IStringMatcher stringMatcher)
{
// If the body is a JSON object, try to use Body (string) to match.
if (requestMessage.BodyAsJson != null && requestMessage.Body != null)
{
return stringMatcher.IsMatch(requestMessage.Body);
}
// If the string body is defined, try to match.
if (requestMessage.Body != null)
{
return stringMatcher.IsMatch(requestMessage.Body);
}
}
if (Func != null)
{
return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));

View File

@@ -25,7 +25,8 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
/// </summary>
/// <param name="clientIPs">The clientIPs.</param>
public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(ip)).Cast<IStringMatcher>().ToArray())
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageClientIPMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(matchBehaviour, ip)).Cast<IStringMatcher>().ToArray())
{
}

View File

@@ -11,6 +11,8 @@ namespace WireMock.Matchers.Request
/// </summary>
public class RequestMessageCookieMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
/// <value>
/// The funcs.
/// </value>
@@ -29,16 +31,18 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">The ignoreCase.</param>
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
}
/// <summary>
@@ -77,7 +81,7 @@ namespace WireMock.Matchers.Request
{
if (requestMessage.Cookies == null)
{
return MatchScores.Mismatch;
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
if (Funcs != null)
@@ -92,7 +96,7 @@ namespace WireMock.Matchers.Request
if (!requestMessage.Cookies.ContainsKey(Name))
{
return MatchScores.Mismatch;
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
string value = requestMessage.Cookies[Name];

View File

@@ -13,6 +13,8 @@ namespace WireMock.Matchers.Request
/// <inheritdoc cref="IRequestMatcher"/>
public class RequestMessageHeaderMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
/// <summary>
/// The functions
/// </summary>
@@ -33,14 +35,16 @@ namespace WireMock.Matchers.Request
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string pattern, bool ignoreCase)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };
}
/// <summary>
@@ -48,14 +52,16 @@ namespace WireMock.Matchers.Request
/// </summary>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string[] patterns, bool ignoreCase = true)
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string[] patterns, bool ignoreCase)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_matchBehaviour = matchBehaviour;
Name = name;
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
Matchers = patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
}
/// <summary>
@@ -94,7 +100,7 @@ namespace WireMock.Matchers.Request
{
if (requestMessage.Headers == null)
{
return MatchScores.Mismatch;
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
if (Funcs != null)
@@ -109,7 +115,7 @@ namespace WireMock.Matchers.Request
if (!requestMessage.Headers.ContainsKey(Name))
{
return MatchScores.Mismatch;
return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);
}
WireMockList<string> list = requestMessage.Headers[Name];

View File

@@ -9,6 +9,8 @@ namespace WireMock.Matchers.Request
/// </summary>
internal class RequestMessageMethodMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
/// <summary>
/// The methods
/// </summary>
@@ -17,26 +19,20 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class.
/// </summary>
/// <param name="methods">
/// The verb.
/// </param>
public RequestMessageMethodMatcher([NotNull] params string[] methods)
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="methods">The methods.</param>
public RequestMessageMethodMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] methods)
{
Check.NotNull(methods, nameof(methods));
_matchBehaviour = matchBehaviour;
Methods = methods.Select(v => v.ToLower()).ToArray();
}
/// <summary>
/// Determines whether the specified RequestMessage is match.
/// </summary>
/// <param name="requestMessage">The RequestMessage.</param>
/// <param name="requestMatchResult">The RequestMatchResult.</param>
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
return requestMatchResult.AddScore(GetType(), score);
}

View File

@@ -12,6 +12,8 @@ namespace WireMock.Matchers.Request
/// </summary>
public class RequestMessageParamMatcher : IRequestMatcher
{
private readonly MatchBehaviour _matchBehaviour;
/// <summary>
/// The funcs
/// </summary>
@@ -30,20 +32,23 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="key">The key.</param>
public RequestMessageParamMatcher([NotNull] string key) : this(key, null)
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key) : this(matchBehaviour, key, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="key">The key.</param>
/// <param name="values">The values.</param>
public RequestMessageParamMatcher([NotNull] string key, [CanBeNull] IEnumerable<string> values)
public RequestMessageParamMatcher(MatchBehaviour matchBehaviour, [NotNull] string key, [CanBeNull] IEnumerable<string> values)
{
Check.NotNull(key, nameof(key));
_matchBehaviour = matchBehaviour;
Key = key;
Values = values;
}
@@ -62,7 +67,7 @@ namespace WireMock.Matchers.Request
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);
double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));
return requestMatchResult.AddScore(GetType(), score);
}

View File

@@ -12,7 +12,7 @@ namespace WireMock.Matchers.Request
public class RequestMessagePathMatcher : IRequestMatcher
{
/// <summary>
/// The matcher.
/// The matchers
/// </summary>
public IReadOnlyList<IStringMatcher> Matchers { get; }
@@ -24,8 +24,9 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="paths">The paths.</param>
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).Cast<IStringMatcher>().ToArray())
public RequestMessagePathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(matchBehaviour, path)).Cast<IStringMatcher>().ToArray())
{
}
@@ -36,6 +37,7 @@ namespace WireMock.Matchers.Request
public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(matchers, nameof(matchers));
Matchers = matchers;
}
@@ -46,6 +48,7 @@ namespace WireMock.Matchers.Request
public RequestMessagePathMatcher([NotNull] params Func<string, bool>[] funcs)
{
Check.NotNull(funcs, nameof(funcs));
Funcs = funcs;
}

View File

@@ -24,8 +24,9 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="urls">The urls.</param>
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).Cast<IStringMatcher>().ToArray())
public RequestMessageUrlMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(matchBehaviour, url)).Cast<IStringMatcher>().ToArray())
{
}

View File

@@ -16,12 +16,25 @@ namespace WireMock.Matchers
private readonly string[] _patterns;
private readonly SimMetricType _simMetricType;
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
/// </summary>
/// <param name="pattern">The pattern.</param>
/// <param name="simMetricType">The SimMetric Type</param>
public SimMetricsMatcher([NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new [] { pattern }, simMetricType)
public SimMetricsMatcher([NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="simMetricType">The SimMetric Type</param>
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType)
{
}
@@ -30,10 +43,21 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="patterns">The patterns.</param>
/// <param name="simMetricType">The SimMetric Type</param>
public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein)
public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="simMetricType">The SimMetric Type</param>
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein)
{
Check.NotNullOrEmpty(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour;
_patterns = patterns;
_simMetricType = simMetricType;
}
@@ -43,7 +67,7 @@ namespace WireMock.Matchers
{
IStringMetric m = GetStringMetricType();
return MatchScores.ToScore(_patterns.Select(p => m.GetSimilarity(p, input)));
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => m.GetSimilarity(p, input))));
}
private IStringMetric GetStringMetricType()
@@ -95,10 +119,7 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return $"SimMetricsMatcher.{_simMetricType}";
}
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => $"SimMetricsMatcher.{_simMetricType}";
}
}

View File

@@ -17,7 +17,17 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase</param>
public WildcardMatcher([NotNull] string pattern, bool ignoreCase = false) : this(new [] { pattern }, ignoreCase)
public WildcardMatcher([NotNull] string pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="WildcardMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase</param>
public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase)
{
}
@@ -26,7 +36,17 @@ namespace WireMock.Matchers
/// </summary>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">IgnoreCase</param>
public WildcardMatcher([NotNull] string[] patterns, bool ignoreCase = false) : base(patterns.Select(pattern => "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$").ToArray(), ignoreCase)
public WildcardMatcher([NotNull] string[] patterns, bool ignoreCase = false) : this(MatchBehaviour.AcceptOnMatch, patterns, ignoreCase)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="WildcardMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">IgnoreCase</param>
public WildcardMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns.Select(pattern => "^" + Regex.Escape(pattern).Replace(@"\*", ".*").Replace(@"\?", ".") + "$").ToArray(), ignoreCase)
{
_patterns = patterns;
}
@@ -37,10 +57,7 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc cref="IMatcher.GetName"/>
public override string GetName()
{
return "WildcardMatcher";
}
/// <inheritdoc cref="IMatcher.Name"/>
public override string Name => "WildcardMatcher";
}
}

View File

@@ -17,38 +17,52 @@ namespace WireMock.Matchers
{
private readonly string[] _patterns;
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="XPathMatcher"/> class.
/// </summary>
/// <param name="patterns">The patterns.</param>
public XPathMatcher([NotNull] params string[] patterns)
public XPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="XPathMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="patterns">The patterns.</param>
public XPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns)
{
Check.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour;
_patterns = patterns;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
if (input == null)
double match = MatchScores.Mismatch;
if (input != null)
{
return MatchScores.Mismatch;
try
{
var nav = new XmlDocument { InnerXml = input }.CreateNavigator();
#if NETSTANDARD1_3
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})"))));
#else
match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))));
#endif
}
catch (Exception)
{
// just ignore exception
}
}
try
{
var nav = new XmlDocument { InnerXml = input }.CreateNavigator();
#if NETSTANDARD1_3
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})"))));
#else
return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))));
#endif
}
catch (Exception)
{
return MatchScores.Mismatch;
}
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
@@ -57,10 +71,7 @@ namespace WireMock.Matchers
return _patterns;
}
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "XPathMatcher";
}
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "XPathMatcher";
}
}

View File

@@ -94,8 +94,6 @@ namespace WireMock.Owin
#endif
.Build();
IsStarted = true;
return Task.Run(() =>
{
StartServers();
@@ -112,7 +110,7 @@ namespace WireMock.Owin
_host.Run(_cts.Token);
#else
_logger.Info("WireMock.Net server using netstandard2.0");
_host.Run();
_host.RunAsync(_cts.Token).Wait();
#endif
}
catch (Exception e)

View File

@@ -24,29 +24,41 @@ namespace WireMock.Owin
// https://msdn.microsoft.com/en-us/library/78h415ay(v=vs.110).aspx
#if !NETSTANDARD
private static readonly IDictionary<string, Action<IOwinResponse, WireMockList<string>>> RestrictedResponseHeaders = new Dictionary<string, Action<IOwinResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
private static readonly IDictionary<string, Action<IOwinResponse, WireMockList<string>>> ResponseHeadersToFix = new Dictionary<string, Action<IOwinResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
#else
private static readonly IDictionary<string, Action<HttpResponse, WireMockList<string>>> RestrictedResponseHeaders = new Dictionary<string, Action<HttpResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
private static readonly IDictionary<string, Action<HttpResponse, WireMockList<string>>> ResponseHeadersToFix = new Dictionary<string, Action<HttpResponse, WireMockList<string>>>(StringComparer.OrdinalIgnoreCase) {
#endif
{ HttpKnownHeaderNames.Accept, null },
{ HttpKnownHeaderNames.Connection, null },
{ HttpKnownHeaderNames.ContentLength, null },
{ HttpKnownHeaderNames.ContentType, (r, v) => r.ContentType = v.FirstOrDefault() },
{ HttpKnownHeaderNames.Date, null },
{ HttpKnownHeaderNames.Expect, null },
{ HttpKnownHeaderNames.Host, null },
{ HttpKnownHeaderNames.IfModifiedSince, null },
{ HttpKnownHeaderNames.KeepAlive, null },
{ HttpKnownHeaderNames.Range, null },
{ HttpKnownHeaderNames.Referer, null },
{ HttpKnownHeaderNames.TransferEncoding, null },
{ HttpKnownHeaderNames.UserAgent, null },
{ HttpKnownHeaderNames.ProxyConnection, null },
{ HttpKnownHeaderNames.WWWAuthenticate, null }
{ HttpKnownHeaderNames.ContentType, (r, v) => r.ContentType = v.FirstOrDefault() }
};
private void SetResponseHeaders(ResponseMessage responseMessage
#if !NETSTANDARD
, IOwinResponse response
#else
, HttpResponse response
#endif
)
{
// Set headers
foreach (var pair in responseMessage.Headers)
{
if (ResponseHeadersToFix.ContainsKey(pair.Key))
{
ResponseHeadersToFix[pair.Key]?.Invoke(response, pair.Value);
}
else
{
#if !NETSTANDARD
response.Headers.AppendValues(pair.Key, pair.Value.ToArray());
#else
response.Headers.Append(pair.Key, pair.Value.ToArray());
#endif
}
}
}
/// <summary>
/// MapAsync ResponseMessage to OwinResponse
/// Map ResponseMessage to OwinResponse/HttpResponse
/// </summary>
/// <param name="responseMessage"></param>
/// <param name="response"></param>
@@ -60,57 +72,31 @@ namespace WireMock.Owin
{
response.StatusCode = responseMessage.StatusCode;
// Set headers
foreach (var pair in responseMessage.Headers)
{
if (RestrictedResponseHeaders.ContainsKey(pair.Key))
{
RestrictedResponseHeaders[pair.Key]?.Invoke(response, pair.Value);
}
else
{
#if !NETSTANDARD
response.Headers.AppendValues(pair.Key, pair.Value.ToArray());
#else
response.Headers.Append(pair.Key, pair.Value.ToArray());
#endif
}
}
if (responseMessage.Body == null && responseMessage.BodyAsBytes == null && responseMessage.BodyAsFile == null && responseMessage.BodyAsJson == null)
{
return;
}
byte[] bytes = null;
if (responseMessage.BodyAsBytes != null)
{
await response.Body.WriteAsync(responseMessage.BodyAsBytes, 0, responseMessage.BodyAsBytes.Length);
return;
bytes = responseMessage.BodyAsBytes;
}
if (responseMessage.BodyAsFile != null)
else if (responseMessage.BodyAsFile != null)
{
byte[] bytes = File.ReadAllBytes(responseMessage.BodyAsFile);
await response.Body.WriteAsync(bytes, 0, bytes.Length);
return;
bytes = File.ReadAllBytes(responseMessage.BodyAsFile);
}
if (responseMessage.BodyAsJson != null)
else if (responseMessage.BodyAsJson != null)
{
Formatting formatting = responseMessage.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
using (var writer = new StreamWriter(response.Body, responseMessage.BodyEncoding ?? _utf8NoBom))
{
await writer.WriteAsync(jsonBody);
}
return;
bytes = (responseMessage.BodyEncoding ?? _utf8NoBom).GetBytes(jsonBody);
}
else if (responseMessage.Body != null)
{
bytes = (responseMessage.BodyEncoding ?? _utf8NoBom).GetBytes(responseMessage.Body);
}
using (var writer = new StreamWriter(response.Body, responseMessage.BodyEncoding ?? _utf8NoBom))
SetResponseHeaders(responseMessage, response);
if (bytes != null)
{
await writer.WriteAsync(responseMessage.Body);
await response.Body.WriteAsync(bytes, 0, bytes.Length);
}
}
}

View File

@@ -7,6 +7,7 @@ using WireMock.Matchers;
using WireMock.Util;
using Newtonsoft.Json;
using WireMock.Http;
using WireMock.Serialization;
#if !NETSTANDARD
using Microsoft.Owin;
#else
@@ -58,7 +59,7 @@ namespace WireMock.Owin
// Set start
if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)
{
_options.Scenarios.Add(mapping.Scenario, null);
_options.Scenarios.TryAdd(mapping.Scenario, null);
}
}
@@ -153,6 +154,8 @@ namespace WireMock.Owin
private void LogRequest(LogEntry entry, bool addRequest)
{
_options.Logger.DebugRequestResponse(LogEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__admin/"));
if (addRequest)
{
_options.LogEntries.Add(entry);

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using WireMock.Logging;
using WireMock.Matchers;
@@ -23,7 +22,9 @@ namespace WireMock.Owin
public bool AllowPartialMapping { get; set; }
public IDictionary<Guid, Mapping> Mappings { get; } = new ConcurrentDictionary<Guid, Mapping>();
public ConcurrentDictionary<Guid, Mapping> Mappings { get; } = new ConcurrentDictionary<Guid, Mapping>(); // Checked
public ConcurrentDictionary<string, object> Scenarios { get; } = new ConcurrentDictionary<string, object>(); // Checked
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurentObservableCollection<LogEntry>();
@@ -31,8 +32,6 @@ namespace WireMock.Owin
public int? MaxRequestLogCount { get; set; }
public IDictionary<string, object> Scenarios { get; } = new ConcurrentDictionary<string, object>();
#if !NETSTANDARD
public Action<IAppBuilder> PreWireMockMiddlewareInit { get; set; }

View File

@@ -20,39 +20,42 @@ namespace WireMock.RequestBuilders
/// WithBody: Body as string
/// </summary>
/// <param name="body">The body.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(string body);
IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithBody: Body as byte[]
/// </summary>
/// <param name="body">The body.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(byte[] body);
IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithBody: Body as object
/// </summary>
/// <param name="body">The body.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(object body);
IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
///WithBody: func (string)
/// WithBody: func (string)
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<string, bool> func);
/// <summary>
///WithBody: func (byte[])
/// WithBody: func (byte[])
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<byte[], bool> func);
/// <summary>
///WithBody: func (object)
/// WithBody: func (object)
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>

View File

@@ -10,21 +10,29 @@ namespace WireMock.RequestBuilders
public interface IClientIPRequestBuilder : IUrlAndPathRequestBuilder
{
/// <summary>
/// The with ClientIP.
/// WithClientIP: add matching on ClientIP matchers.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP([NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with ClientIP.
/// WithClientIP: add matching on clientIPs.
/// </summary>
/// <param name="clientIPs">The clientIPs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP([NotNull] params string[] clientIPs);
/// <summary>
/// The with ClientIP.
/// WithClientIP: add matching on clientIPs and matchBehaviour.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="clientIPs">The clientIPs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP(MatchBehaviour matchBehaviour, [NotNull] params string[] clientIPs);
/// <summary>
/// WithClientIP: add matching on ClientIP funcs.
/// </summary>
/// <param name="funcs">The path funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>

View File

@@ -12,25 +12,45 @@ namespace WireMock.RequestBuilders
public interface IHeadersAndCookiesRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
{
/// <summary>
/// Add Header matching based on name, pattern and ignoreCase.
/// WithHeader: matching based on name, pattern and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true);
IRequestBuilder WithHeader([NotNull] string name, string pattern, MatchBehaviour matchBehaviour);
/// <summary>
/// Add Header matching based on name, patterns and ignoreCase.
/// WithHeader: matching based on name, pattern, ignoreCase and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithHeader: matching based on name, patterns and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, bool ignoreCase = true);
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, MatchBehaviour matchBehaviour);
/// <summary>
/// The with header.
/// WithHeader: matching based on name, patterns, ignoreCase and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithHeader: matching based on name and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
@@ -38,23 +58,24 @@ namespace WireMock.RequestBuilders
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with header.
/// WithHeader: matching based on functions.
/// </summary>
/// <param name="funcs">The headers funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs);
/// <summary>
/// The with cookie.
/// WithCookie: cookie matching based on name, pattern, ignoreCase and matchBehaviour.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <param name="ignoreCase">Ignore the case from the pattern.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true);
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The with cookie.
/// WithCookie: matching based on name and IStringMatcher[].
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
@@ -62,7 +83,7 @@ namespace WireMock.RequestBuilders
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with cookie.
/// WithCookie: matching based on functions.
/// </summary>
/// <param name="cookieFuncs">The funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>

View File

@@ -1,4 +1,6 @@
using JetBrains.Annotations;
using System;
using JetBrains.Annotations;
using WireMock.Matchers;
namespace WireMock.RequestBuilders
{
@@ -8,66 +10,81 @@ namespace WireMock.RequestBuilders
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
{
/// <summary>
/// The using delete.
/// UsingDelete: add HTTP Method matching on `delete` and matchBehaviour (optional).
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingDelete();
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The using get.
/// UsingGet: add HTTP Method matching on `get` and matchBehaviour (optional).
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingGet();
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The using head.
/// Add HTTP Method matching on `head` and matchBehaviour (optional).
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingHead();
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The using post.
/// UsingPost: add HTTP Method matching on `post` and matchBehaviour (optional).
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingPost();
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The using patch.
/// UsingPatch: add HTTP Method matching on `patch` and matchBehaviour (optional).
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingPatch();
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The using put.
/// UsingPut: add HTTP Method matching on `put` and matchBehaviour (optional).
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingPut();
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// The using any verb.
/// UsingAnyMethod: add HTTP Method matching on any method.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingAnyMethod();
/// <summary>
/// UsingAnyVerb: add HTTP Method matching on any method.
/// </summary>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
[Obsolete]
IRequestBuilder UsingAnyVerb();
/// <summary>
/// The using verb.
/// UsingMethod: add HTTP Method matching on any methods and matchBehaviour.
/// </summary>
/// <param name="verbs">The verb.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="methods">The methods.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, [NotNull] params string[] methods);
/// <summary>
/// UsingMethod: add HTTP Method matching on any methods.
/// </summary>
/// <param name="methods">The methods.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingMethod([NotNull] params string[] methods);
/// <summary>
/// UsingVerb: add HTTP Method matching on any methods.
/// </summary>
/// <param name="verbs">The methods.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
[Obsolete]
IRequestBuilder UsingVerb([NotNull] params string[] verbs);
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using WireMock.Matchers;
using WireMock.Util;
namespace WireMock.RequestBuilders
@@ -11,14 +12,15 @@ namespace WireMock.RequestBuilders
public interface IParamsRequestBuilder
{
/// <summary>
/// WithParam (key only)
/// WithParam: matching on key only.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="matchBehaviour">The match behaviour (optional).</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithParam([NotNull] string key);
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
/// <summary>
/// WithParam (values)
/// WithParam: matching on key and values.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="values">The values.</param>
@@ -26,7 +28,16 @@ namespace WireMock.RequestBuilders
IRequestBuilder WithParam([NotNull] string key, [CanBeNull] params string[] values);
/// <summary>
/// WithParam (funcs)
/// WithParam: matching on key, values and matchBehaviour.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="values">The values.</param>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithParam([NotNull] string key, MatchBehaviour matchBehaviour, [CanBeNull] params string[] values);
/// <summary>
/// WithParam: matching on functions.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>

View File

@@ -10,42 +10,58 @@ namespace WireMock.RequestBuilders
public interface IUrlAndPathRequestBuilder : IMethodRequestBuilder
{
/// <summary>
/// The with path.
/// WithPath: add path matching based on IStringMatchers.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with path.
/// WithPath: add path matching based on paths.
/// </summary>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params string[] paths);
/// <summary>
/// The with path.
/// WithPath: add path matching based on paths and matchBehaviour.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath(MatchBehaviour matchBehaviour, [NotNull] params string[] paths);
/// <summary>
/// WithPath: add path matching based on functions.
/// </summary>
/// <param name="funcs">The path funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params Func<string, bool>[] funcs);
/// <summary>
/// The with url.
/// WithUrl: add url matching based on IStringMatcher[].
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with url.
/// WithUrl: add url matching based on urls.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params string[] urls);
/// <summary>
/// The with path.
/// WithUrl: add url matching based on urls.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl(MatchBehaviour matchBehaviour, [NotNull] params string[] urls);
/// <summary>
/// WithUrl: add url matching based on functions.
/// </summary>
/// <param name="func">The path func.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>

View File

@@ -54,11 +54,7 @@ namespace WireMock.RequestBuilders
return _requestMatchers.Where(rm => rm is T).Cast<T>().FirstOrDefault();
}
/// <summary>
/// The with clientIP.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(IStringMatcher[])"/>
public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -67,24 +63,22 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with clientIP.
/// </summary>
/// <param name="clientIPs">The ClientIPs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(string[])"/>
public IRequestBuilder WithClientIP(params string[] clientIPs)
{
return WithClientIP(MatchBehaviour.AcceptOnMatch, clientIPs);
}
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(string[])"/>
public IRequestBuilder WithClientIP(MatchBehaviour matchBehaviour, params string[] clientIPs)
{
Check.NotNullOrEmpty(clientIPs, nameof(clientIPs));
_requestMatchers.Add(new RequestMessageClientIPMatcher(clientIPs));
_requestMatchers.Add(new RequestMessageClientIPMatcher(matchBehaviour, clientIPs));
return this;
}
/// <summary>
/// The with clientIP.
/// </summary>
/// <param name="funcs">The clientIP funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(Func{string, bool}[])"/>
public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
@@ -93,11 +87,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with path.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(IStringMatcher[])"/>
public IRequestBuilder WithPath(params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -106,24 +96,22 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with path.
/// </summary>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(string[])"/>
public IRequestBuilder WithPath(params string[] paths)
{
return WithPath(MatchBehaviour.AcceptOnMatch, paths);
}
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(MatchBehaviour, string[])"/>
public IRequestBuilder WithPath(MatchBehaviour matchBehaviour, params string[] paths)
{
Check.NotNullOrEmpty(paths, nameof(paths));
_requestMatchers.Add(new RequestMessagePathMatcher(paths));
_requestMatchers.Add(new RequestMessagePathMatcher(matchBehaviour, paths));
return this;
}
/// <summary>
/// The with path.
/// </summary>
/// <param name="funcs">The path func.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(Func{string, bool}[])"/>
public IRequestBuilder WithPath(params Func<string, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
@@ -132,11 +120,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with url.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(IStringMatcher[])"/>
public IRequestBuilder WithUrl(params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -145,24 +129,22 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with url.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(string[])"/>
public IRequestBuilder WithUrl(params string[] urls)
{
return WithUrl(MatchBehaviour.AcceptOnMatch, urls);
}
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(MatchBehaviour, string[])"/>
public IRequestBuilder WithUrl(MatchBehaviour matchBehaviour, params string[] urls)
{
Check.NotNullOrEmpty(urls, nameof(urls));
_requestMatchers.Add(new RequestMessageUrlMatcher(urls));
_requestMatchers.Add(new RequestMessageUrlMatcher(matchBehaviour, urls));
return this;
}
/// <summary>
/// The with url.
/// </summary>
/// <param name="funcs">The url func.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(Func{string, bool}[])"/>
public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
@@ -171,50 +153,50 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete"/>
public IRequestBuilder UsingDelete()
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher("delete"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "delete"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet"/>
public IRequestBuilder UsingGet()
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher("get"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "get"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead"/>
public IRequestBuilder UsingHead()
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher("head"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "head"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost"/>
public IRequestBuilder UsingPost()
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher("post"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "post"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch"/>
public IRequestBuilder UsingPatch()
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher("patch"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "patch"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut"/>
public IRequestBuilder UsingPut()
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageMethodMatcher("put"));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "put"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
public IRequestBuilder UsingAnyMethod()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
foreach (var matcher in matchers)
@@ -225,33 +207,51 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb"/>
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
return UsingAnyMethod();
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
public IRequestBuilder UsingMethod(params string[] methods)
{
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
public IRequestBuilder UsingVerb(params string[] verbs)
{
Check.NotNullOrEmpty(verbs, nameof(verbs));
return UsingMethod(verbs);
}
_requestMatchers.Add(new RequestMessageMethodMatcher(verbs));
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
{
Check.NotNullOrEmpty(methods, nameof(methods));
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string)"/>
public IRequestBuilder WithBody(string body)
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[])"/>
public IRequestBuilder WithBody(byte[] body)
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object)"/>
public IRequestBuilder WithBody(object body)
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
return this;
}
@@ -291,21 +291,27 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string)"/>
public IRequestBuilder WithParam(string key)
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour)"/>
public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(key, nameof(key));
_requestMatchers.Add(new RequestMessageParamMatcher(key));
_requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key));
return this;
}
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, string[])"/>
public IRequestBuilder WithParam(string key, params string[] values)
{
return WithParam(key, MatchBehaviour.AcceptOnMatch, values);
}
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour, string[])"/>
public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params string[] values)
{
Check.NotNull(key, nameof(key));
_requestMatchers.Add(new RequestMessageParamMatcher(key, values));
_requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, values));
return this;
}
@@ -318,32 +324,39 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string,bool)"/>
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)
{
return WithHeader(name, pattern, true, matchBehaviour);
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(pattern, nameof(pattern));
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, pattern, ignoreCase));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string[],bool)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true)
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)
{
return WithHeader(name, patterns, true, matchBehaviour);
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, patterns, ignoreCase));
_requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, patterns, ignoreCase));
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, IStringMatcher[])"/>
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
@@ -353,11 +366,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/>
public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
@@ -366,25 +375,14 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// With cookie.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true)
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, string, bool, MatchBehaviour)"/>
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageCookieMatcher(name, pattern, ignoreCase));
_requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, pattern, ignoreCase));
return this;
}
/// <summary>
/// With cookie.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -393,11 +391,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(Func{IDictionary{string, string}, bool}[])"/>
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));

View File

@@ -65,7 +65,7 @@ namespace WireMock
public string RawQuery { get; }
/// <summary>
/// The body as string.
/// The original body as string, this is defined when Body or BodyAsJson are not null.
/// </summary>
public string Body { get; }
@@ -113,7 +113,7 @@ namespace WireMock
/// <param name="body">The body.</param>
/// <param name="headers">The headers.</param>
/// <param name="cookies">The cookies.</param>
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData body, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData body = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
{
Check.NotNull(url, nameof(url));
Check.NotNull(method, nameof(method));
@@ -140,43 +140,6 @@ namespace WireMock
Query = ParseQuery(RawQuery);
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
/// </summary>
/// <param name="url">The original url.</param>
/// <param name="method">The HTTP method.</param>
/// <param name="clientIP">The client IP Address.</param>
/// <param name="bodyAsBytes">The bodyAsBytes byte[].</param>
/// <param name="body">The body string.</param>
/// <param name="bodyEncoding">The body encoding</param>
/// <param name="headers">The headers.</param>
/// <param name="cookies">The cookies.</param>
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
{
Check.NotNull(url, nameof(url));
Check.NotNull(method, nameof(method));
Check.NotNull(clientIP, nameof(clientIP));
Url = url.ToString();
Protocol = url.Scheme;
Host = url.Host;
Port = url.Port;
Origin = $"{url.Scheme}://{url.Host}:{url.Port}";
Path = WebUtility.UrlDecode(url.AbsolutePath);
PathSegments = Path.Split('/').Skip(1).ToArray();
Method = method.ToLower();
ClientIP = clientIP;
BodyAsBytes = bodyAsBytes;
Body = body;
BodyEncoding = bodyEncoding;
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
Cookies = cookies;
RawQuery = WebUtility.UrlDecode(url.Query);
Query = ParseQuery(RawQuery);
}
private static IDictionary<string, WireMockList<string>> ParseQuery(string queryString)
{
if (string.IsNullOrEmpty(queryString))

View File

@@ -1,5 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WireMock.Util;
@@ -8,14 +7,14 @@ using WireMock.Validation;
namespace WireMock
{
/// <summary>
/// The response.
/// The ResponseMessage.
/// </summary>
public class ResponseMessage
{
/// <summary>
/// Gets the headers.
/// </summary>
public IDictionary<string, WireMockList<string>> Headers { get; set; } = new ConcurrentDictionary<string, WireMockList<string>>();
public IDictionary<string, WireMockList<string>> Headers { get; set; } = new Dictionary<string, WireMockList<string>>();
/// <summary>
/// Gets or sets the status code.

View File

@@ -0,0 +1,70 @@
using System.Linq;
using WireMock.Admin.Mappings;
using WireMock.Admin.Requests;
using WireMock.Logging;
namespace WireMock.Serialization
{
internal static class LogEntryMapper
{
public static LogEntryModel Map(LogEntry logEntry)
{
return new LogEntryModel
{
Guid = logEntry.Guid,
Request = new LogRequestModel
{
DateTime = logEntry.RequestMessage.DateTime,
ClientIP = logEntry.RequestMessage.ClientIP,
Path = logEntry.RequestMessage.Path,
AbsoluteUrl = logEntry.RequestMessage.Url,
Query = logEntry.RequestMessage.Query,
Method = logEntry.RequestMessage.Method,
Body = logEntry.RequestMessage.Body,
BodyAsJson = logEntry.RequestMessage.BodyAsJson,
BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
Headers = logEntry.RequestMessage.Headers,
Cookies = logEntry.RequestMessage.Cookies,
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
WebName = logEntry.RequestMessage.BodyEncoding.WebName
} : null
},
Response = new LogResponseModel
{
StatusCode = logEntry.ResponseMessage.StatusCode,
BodyDestination = logEntry.ResponseMessage.BodyDestination,
Body = logEntry.ResponseMessage.Body,
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
Headers = logEntry.ResponseMessage.Headers,
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
WebName = logEntry.ResponseMessage.BodyEncoding.WebName
} : null
},
MappingGuid = logEntry.MappingGuid,
MappingTitle = logEntry.MappingTitle,
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
{
TotalScore = logEntry.RequestMatchResult.TotalScore,
TotalNumber = logEntry.RequestMatchResult.TotalNumber,
IsPerfectMatch = logEntry.RequestMatchResult.IsPerfectMatch,
AverageTotalScore = logEntry.RequestMatchResult.AverageTotalScore,
MatchDetails = logEntry.RequestMatchResult.MatchDetails.Select(x => new
{
Name = x.Key.Name.Replace("RequestMessage", string.Empty),
Score = x.Value
} as object).ToList()
} : null
};
}
}
}

View File

@@ -22,11 +22,13 @@ namespace WireMock.Serialization
string[] patterns = matcher is IStringMatcher stringMatcher ? stringMatcher.GetPatterns() : new string[0];
bool? ignorecase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : (bool?)null;
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : (bool?) null;
return new MatcherModel
{
RejectOnMatch = rejectOnMatch,
IgnoreCase = ignorecase,
Name = matcher.GetName(),
Name = matcher.Name,
Pattern = patterns.Length == 1 ? patterns.First() : null,
Patterns = patterns.Length > 1 ? patterns : null
};

View File

@@ -20,23 +20,24 @@ namespace WireMock.Serialization
string matcherType = parts.Length > 1 ? parts[1] : null;
string[] patterns = matcher.Patterns ?? new[] { matcher.Pattern };
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
switch (matcherName)
{
case "ExactMatcher":
return new ExactMatcher(patterns);
return new ExactMatcher(matchBehaviour, patterns);
case "RegexMatcher":
return new RegexMatcher(patterns, matcher.IgnoreCase == true);
return new RegexMatcher(matchBehaviour, patterns, matcher.IgnoreCase == true);
case "JsonPathMatcher":
return new JsonPathMatcher(patterns);
return new JsonPathMatcher(matchBehaviour, patterns);
case "XPathMatcher":
return new XPathMatcher(matcher.Pattern);
return new XPathMatcher(matchBehaviour, matcher.Pattern);
case "WildcardMatcher":
return new WildcardMatcher(patterns, matcher.IgnoreCase == true);
return new WildcardMatcher(matchBehaviour, patterns, matcher.IgnoreCase == true);
case "SimMetricsMatcher":
SimMetricType type = SimMetricType.Levenstein;
@@ -45,7 +46,7 @@ namespace WireMock.Serialization
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
}
return new SimMetricsMatcher(matcher.Pattern, type);
return new SimMetricsMatcher(matchBehaviour, matcher.Pattern, type);
default:
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");

View File

@@ -36,8 +36,8 @@ namespace WireMock.Server
private const string AdminRequests = "/__admin/requests";
private const string AdminSettings = "/__admin/settings";
private const string AdminScenarios = "/__admin/scenarios";
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/mappings\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/requests\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/mappings\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/requests\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
@@ -50,7 +50,7 @@ namespace WireMock.Server
{
// __admin/settings
Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsGet));
Given(Request.Create().WithPath(AdminSettings).UsingVerb("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(SettingsUpdate));
Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.ContentType, ContentTypeJson)).RespondWith(new DynamicResponseProvider(SettingsUpdate));
// __admin/mappings
@@ -196,7 +196,7 @@ namespace WireMock.Server
private void InitProxyAndRecord(IProxyAndRecordSettings settings)
{
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ClientX509Certificate2ThumbprintOrSubjectName);
Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
Given(Request.Create().WithPath("/*").UsingAnyMethod()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
}
private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings settings)
@@ -210,7 +210,7 @@ namespace WireMock.Server
if (settings.SaveMapping)
{
var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { });
_options.Mappings.Add(mapping.Guid, mapping);
_options.Mappings.TryAdd(mapping.Guid, mapping);
if (settings.SaveMappingToFile)
{
@@ -225,7 +225,7 @@ namespace WireMock.Server
{
var request = Request.Create();
request.WithPath(requestMessage.Path);
request.UsingVerb(requestMessage.Method);
request.UsingMethod(requestMessage.Method);
requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
@@ -241,7 +241,7 @@ namespace WireMock.Server
if (requestMessage.Body != null)
{
request.WithBody(new ExactMatcher(requestMessage.Body));
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
}
var response = Response.Create(responseMessage);
@@ -457,7 +457,7 @@ namespace WireMock.Server
return new ResponseMessage { StatusCode = 404, Body = "Request not found" };
}
var model = ToLogEntryModel(entry);
var model = LogEntryMapper.Map(entry);
return ToJson(model);
}
@@ -478,71 +478,11 @@ namespace WireMock.Server
{
var result = LogEntries
.Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
.Select(ToLogEntryModel);
.Select(LogEntryMapper.Map);
return ToJson(result);
}
private LogEntryModel ToLogEntryModel(LogEntry logEntry)
{
return new LogEntryModel
{
Guid = logEntry.Guid,
Request = new LogRequestModel
{
DateTime = logEntry.RequestMessage.DateTime,
ClientIP = logEntry.RequestMessage.ClientIP,
Path = logEntry.RequestMessage.Path,
AbsoluteUrl = logEntry.RequestMessage.Url,
Query = logEntry.RequestMessage.Query,
Method = logEntry.RequestMessage.Method,
Body = logEntry.RequestMessage.Body,
BodyAsJson = logEntry.RequestMessage.BodyAsJson,
BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
Headers = logEntry.RequestMessage.Headers,
Cookies = logEntry.RequestMessage.Cookies,
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
WebName = logEntry.RequestMessage.BodyEncoding.WebName
} : null
},
Response = new LogResponseModel
{
StatusCode = logEntry.ResponseMessage.StatusCode,
BodyDestination = logEntry.ResponseMessage.BodyDestination,
Body = logEntry.ResponseMessage.Body,
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
Headers = logEntry.ResponseMessage.Headers,
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
{
EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
WebName = logEntry.ResponseMessage.BodyEncoding.WebName
} : null
},
MappingGuid = logEntry.MappingGuid,
MappingTitle = logEntry.MappingTitle,
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
{
TotalScore = logEntry.RequestMatchResult.TotalScore,
TotalNumber = logEntry.RequestMatchResult.TotalNumber,
IsPerfectMatch = logEntry.RequestMatchResult.IsPerfectMatch,
AverageTotalScore = logEntry.RequestMatchResult.AverageTotalScore,
MatchDetails = logEntry.RequestMatchResult.MatchDetails.Select(x => new
{
Name = x.Key.Name.Replace("RequestMessage", string.Empty),
Score = x.Value
} as object).ToList()
} : null
};
}
private ResponseMessage RequestsDelete(RequestMessage requestMessage)
{
ResetLogEntries();
@@ -568,7 +508,7 @@ namespace WireMock.Server
}
}
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(ToLogEntryModel);
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(LogEntryMapper.Map);
return ToJson(result);
}
@@ -577,7 +517,7 @@ namespace WireMock.Server
#region Scenarios
private ResponseMessage ScenariosGet(RequestMessage requestMessage)
{
var scenarios = Scenarios.Select(s => new
var scenarios = Scenarios.ToArray().Select(s => new
{
Name = s.Key,
Started = s.Value != null,
@@ -648,7 +588,7 @@ namespace WireMock.Server
if (requestModel.Methods != null)
{
requestBuilder = requestBuilder.UsingVerb(requestModel.Methods);
requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);
}
if (requestModel.Headers != null)

View File

@@ -56,7 +56,7 @@ namespace WireMock.Server
/// Gets the scenarios.
/// </summary>
[PublicAPI]
public IDictionary<string, object> Scenarios => new ConcurrentDictionary<string, object>(_options.Scenarios);
public ConcurrentDictionary<string, object> Scenarios => new ConcurrentDictionary<string, object>(_options.Scenarios); // Checked
#region Start/Stop
/// <summary>
@@ -161,6 +161,7 @@ namespace WireMock.Server
settings.Logger = settings.Logger ?? new WireMockConsoleLogger();
_logger = settings.Logger;
_logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
_logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
if (settings.Urls != null)
@@ -195,11 +196,13 @@ namespace WireMock.Server
{
throw new Exception($"Service start failed with error: {_httpServer.RunningException.Message}", _httpServer.RunningException);
}
// Respect start timeout setting by throwing TimeoutException
if (ctsStartTimeout.IsCancellationRequested)
{
throw new TimeoutException($"Service start timed out after {TimeSpan.FromMilliseconds(settings.StartTimeout)}");
}
ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelay);
}
}
@@ -246,7 +249,9 @@ namespace WireMock.Server
[PublicAPI]
public void Stop()
{
_httpServer?.StopAsync();
var result = _httpServer?.StopAsync();
if (result != null)
result.Wait(); //wait for stop to actually happen
}
#endregion
@@ -256,7 +261,7 @@ namespace WireMock.Server
[PublicAPI]
public void AddCatchAllMapping()
{
Given(Request.Create().WithPath("/*").UsingAnyVerb())
Given(Request.Create().WithPath("/*").UsingAnyMethod())
.WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
.AtPriority(1000)
.RespondWith(new DynamicResponseProvider(request => new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" }));
@@ -290,9 +295,9 @@ namespace WireMock.Server
[PublicAPI]
public void ResetMappings()
{
foreach (var nonAdmin in _options.Mappings.Where(m => !m.Value.IsAdminInterface))
foreach (var nonAdmin in _options.Mappings.ToArray().Where(m => !m.Value.IsAdminInterface))
{
_options.Mappings.Remove(nonAdmin);
_options.Mappings.TryRemove(nonAdmin.Key, out _);
}
}
@@ -306,7 +311,7 @@ namespace WireMock.Server
// Check a mapping exists with the same GUID, if so, remove it.
if (_options.Mappings.ContainsKey(guid))
{
return _options.Mappings.Remove(guid);
return _options.Mappings.TryRemove(guid, out _);
}
return false;
@@ -315,7 +320,7 @@ namespace WireMock.Server
private bool DeleteMapping(string path)
{
// Check a mapping exists with the same path, if so, remove it.
var mapping = _options.Mappings.FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase));
var mapping = _options.Mappings.ToArray().FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparison.OrdinalIgnoreCase));
return DeleteMapping(mapping.Key);
}
@@ -351,7 +356,7 @@ namespace WireMock.Server
Check.NotNull(password, nameof(password));
string authorization = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
_options.AuthorizationMatcher = new RegexMatcher("^(?i)BASIC " + authorization + "$");
_options.AuthorizationMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, "^(?i)BASIC " + authorization + "$");
}
/// <summary>
@@ -413,7 +418,7 @@ namespace WireMock.Server
}
else
{
_options.Mappings.Add(mapping.Guid, mapping);
_options.Mappings.TryAdd(mapping.Guid, mapping);
}
}
}

View File

@@ -13,7 +13,7 @@ namespace WireMock.Util
public Encoding Encoding { get; set; }
/// <summary>
/// The body as string.
/// The body as string, this is defined when BodyAsString or BodyAsJson are not null.
/// </summary>
public string BodyAsString { get; set; }

View File

@@ -58,6 +58,7 @@ namespace WireMock.Util
else if (contentTypeHeaderValue != null && contentTypeHeaderValue.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
var stringData = await ReadStringAsync(stream);
data.BodyAsString = stringData.Item1;
data.Encoding = stringData.Item2;
try

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
<AssemblyTitle>WireMock.Net</AssemblyTitle>
<Version>1.0.3.16</Version>
<Version>1.0.4.0</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@@ -36,10 +36,6 @@
<Compile Remove="Util\NamedReaderWriterLocker.cs" />
</ItemGroup>
<ItemGroup>
<None Remove="Server\FluentMockServer.cs~RF44936b9f.TMP" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="11.1.0">
<PrivateAssets>All</PrivateAssets>

View File

@@ -5,7 +5,6 @@ using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using NFluent;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
@@ -190,29 +189,30 @@ namespace WireMock.Net.Tests
[Fact]
public async Task FluentMockServer_Proxy_Should_change_absolute_location_header_in_proxied_response()
{
// given
_serverForProxyForwarding = FluentMockServer.Start();
// Assign
var settings = new FluentMockServerSettings { AllowPartialMapping = false };
_serverForProxyForwarding = FluentMockServer.Start(settings);
_serverForProxyForwarding
.Given(Request.Create().WithPath("/*"))
.RespondWith(Response.Create()
.WithStatusCode(HttpStatusCode.Redirect)
.WithHeader("Location", _serverForProxyForwarding.Urls[0] + "testpath"));
_server = FluentMockServer.Start();
_server = FluentMockServer.Start(settings);
_server
.Given(Request.Create().WithPath("/*"))
.Given(Request.Create().WithPath("/prx"))
.RespondWith(Response.Create().WithProxy(_serverForProxyForwarding.Urls[0]));
// when
// Act
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(_server.Urls[0])
RequestUri = new Uri(_server.Urls[0] + "/prx")
};
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
var response = await new HttpClient(httpClientHandler).SendAsync(requestMessage);
// then
// Assert
Check.That(response.Headers.Contains("Location")).IsTrue();
Check.That(response.Headers.GetValues("Location")).ContainsExactly(_server.Urls[0] + "testpath");
}

View File

@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using NFluent;
using WireMock.Matchers;
@@ -18,6 +20,7 @@ namespace WireMock.Net.Tests
public partial class FluentMockServerTests : IDisposable
{
private FluentMockServer _server;
private static string jsonRequestMessage = @"{ ""message"" : ""Hello server"" }";
// For for AppVeyor + OpenCover
private string GetCurrentFolder()
@@ -218,7 +221,7 @@ namespace WireMock.Net.Tests
// given
_server = FluentMockServer.Start();
_server.Given(Request.Create().WithPath("/foo").UsingVerb("patch"))
_server.Given(Request.Create().WithPath("/foo").UsingMethod("patch"))
.RespondWith(Response.Create().WithBody("hello patch"));
// when
@@ -268,7 +271,7 @@ namespace WireMock.Net.Tests
_server = FluentMockServer.Start();
_server
.Given(Request.Create().UsingAnyVerb())
.Given(Request.Create().UsingAnyMethod())
.RespondWith(Response.Create().WithBodyAsJson(new { message = "Hello" }));
// Act
@@ -285,7 +288,7 @@ namespace WireMock.Net.Tests
_server = FluentMockServer.Start();
_server
.Given(Request.Create().UsingAnyVerb())
.Given(Request.Create().UsingAnyMethod())
.RespondWith(Response.Create().WithBodyAsJson(new { message = "Hello" }, true));
// Act
@@ -348,6 +351,43 @@ namespace WireMock.Net.Tests
Check.That(responseAsBytes).ContainsExactly(new byte[] { 48, 49 });
}
[Fact]
public async Task FluentMockServer_Should_respond_to_valid_matchers_when_sent_json()
{
// Assign
var validMatchersForHelloServerJsonMessage = new List<object[]>
{
new object[] { new WildcardMatcher("*Hello server*"), "application/json" },
new object[] { new WildcardMatcher("*Hello server*"), "text/plain" },
new object[] { new ExactMatcher(jsonRequestMessage), "application/json" },
new object[] { new ExactMatcher(jsonRequestMessage), "text/plain" },
new object[] { new RegexMatcher("Hello server"), "application/json" },
new object[] { new RegexMatcher("Hello server"), "text/plain" },
new object[] { new JsonPathMatcher("$..[?(@.message == 'Hello server')]"), "application/json" },
new object[] { new JsonPathMatcher("$..[?(@.message == 'Hello server')]"), "text/plain" }
};
_server = FluentMockServer.Start();
foreach (var item in validMatchersForHelloServerJsonMessage)
{
_server
.Given(Request.Create().WithPath("/foo").WithBody((IMatcher)item[0]))
.RespondWith(Response.Create().WithBody("Hello client"));
// Act
var content = new StringContent(jsonRequestMessage, Encoding.UTF8, (string)item[1]);
var response = await new HttpClient().PostAsync("http://localhost:" + _server.Ports[0] + "/foo", content);
// Assert
var responseString = await response.Content.ReadAsStringAsync();
Check.That(responseString).Equals("Hello client");
_server.ResetMappings();
_server.ResetLogEntries();
}
}
[Fact]
public async Task FluentMockServer_Should_respond_404_for_unexpected_request()
{
@@ -545,28 +585,10 @@ namespace WireMock.Net.Tests
Check.That(response).IsEqualTo("/fooBar");
}
[Fact]
public async Task FluentMockServer_Should_IgnoreRestrictedHeader()
{
// Assign
_server = FluentMockServer.Start();
_server
.Given(Request.Create().WithPath("/head").UsingHead())
.RespondWith(Response.Create().WithHeader("Content-Length", "1024"));
var request = new HttpRequestMessage(HttpMethod.Head, "http://localhost:" + _server.Ports[0] + "/head");
// Act
var response = await new HttpClient().SendAsync(request);
// Assert
Check.That(response.Content.Headers.GetValues("Content-Length")).ContainsExactly("0");
}
public void Dispose()
{
_server?.Stop();
_serverForProxyForwarding?.Stop();
}
}
}
}

View File

@@ -0,0 +1,25 @@
using NFluent;
using WireMock.Matchers;
using Xunit;
namespace WireMock.Net.Tests
{
public class MatchBehaviourHelperTests
{
[Fact]
public void MatchBehaviourHelper_Convert_AcceptOnMatch()
{
Check.That(MatchBehaviourHelper.Convert(MatchBehaviour.AcceptOnMatch, 0.0)).IsEqualTo(0.0);
Check.That(MatchBehaviourHelper.Convert(MatchBehaviour.AcceptOnMatch, 0.5)).IsEqualTo(0.5);
Check.That(MatchBehaviourHelper.Convert(MatchBehaviour.AcceptOnMatch, 1.0)).IsEqualTo(1.0);
}
[Fact]
public void MatchBehaviourHelper_Convert_RejectOnMatch()
{
Check.That(MatchBehaviourHelper.Convert(MatchBehaviour.RejectOnMatch, 0.0)).IsEqualTo(1.0);
Check.That(MatchBehaviourHelper.Convert(MatchBehaviour.RejectOnMatch, 0.5)).IsEqualTo(0.0);
Check.That(MatchBehaviourHelper.Convert(MatchBehaviour.RejectOnMatch, 1.0)).IsEqualTo(0.0);
}
}
}

View File

@@ -13,7 +13,7 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new ExactMatcher("X");
// Act
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("ExactMatcher");
@@ -46,7 +46,7 @@ namespace WireMock.Net.Tests.Matchers
}
[Fact]
public void Request_WithBodyExactMatcher_false()
public void ExactMatcher_IsMatch_SinglePattern()
{
// Assign
var matcher = new ExactMatcher("cat");
@@ -55,7 +55,33 @@ namespace WireMock.Net.Tests.Matchers
double result = matcher.IsMatch("caR");
// Assert
Check.That(result).IsStrictlyLessThan(1.0);
Check.That(result).IsEqualTo(0.0);
}
[Fact]
public void ExactMatcher_IsMatch_SinglePattern_AcceptOnMatch()
{
// Assign
var matcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, "cat");
// Act
double result = matcher.IsMatch("cat");
// Assert
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void ExactMatcher_IsMatch_SinglePattern_RejectOnMatch()
{
// Assign
var matcher = new ExactMatcher(MatchBehaviour.RejectOnMatch, "cat");
// Act
double result = matcher.IsMatch("cat");
// Assert
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -14,10 +14,52 @@ namespace WireMock.Net.Tests.Matchers
// Act
var matcher = new ExactObjectMatcher(obj);
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("ExactObjectMatcher");
}
[Fact]
public void ExactObjectMatcher_IsMatch_ByteArray()
{
// Assign
object checkValue = new byte[] { 1, 2 };
// Act
var matcher = new ExactObjectMatcher(new byte[] { 1, 2 });
double result = matcher.IsMatch(checkValue);
// Assert
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void ExactObjectMatcher_IsMatch_AcceptOnMatch()
{
// Assign
object obj = 1;
// Act
var matcher = new ExactObjectMatcher(obj);
double result = matcher.IsMatch(1);
// Assert
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void ExactObjectMatcher_IsMatch_RejectOnMatch()
{
// Assign
object obj = 1;
// Act
var matcher = new ExactObjectMatcher(MatchBehaviour.RejectOnMatch, obj);
double result = matcher.IsMatch(1);
// Assert
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -14,7 +14,7 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new JsonPathMatcher("X");
// Act
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("JsonPathMatcher");
@@ -78,10 +78,10 @@ namespace WireMock.Net.Tests.Matchers
public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch()
{
// Assign
var matcher = new JsonPathMatcher("xxx");
var matcher = new JsonPathMatcher("");
// Act
double match = matcher.IsMatch("");
double match = matcher.IsMatch("x");
// Assert
Check.That(match).IsEqualTo(0);
@@ -131,5 +131,18 @@ namespace WireMock.Net.Tests.Matchers
// Assert
Check.That(match).IsEqualTo(1);
}
[Fact]
public void JsonPathMatcher_IsMatch_RejectOnMatch()
{
// Assign
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, "$..[?(@.Id == 1)]");
// Act
double match = matcher.IsMatch(JObject.Parse("{\"Id\":1,\"Name\":\"Test\"}"));
// Assert
Check.That(match).IsEqualTo(0.0);
}
}
}

View File

@@ -13,7 +13,7 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new RegexMatcher("");
// Act
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("RegexMatcher");
@@ -32,6 +32,18 @@ namespace WireMock.Net.Tests.Matchers
Check.That(patterns).ContainsExactly("X");
}
[Fact]
public void RegexMatcher_GetIgnoreCase()
{
// Act
bool case1 = new RegexMatcher("X").IgnoreCase;
bool case2 = new RegexMatcher("X", true).IgnoreCase;
// Assert
Check.That(case1).IsFalse();
Check.That(case2).IsTrue();
}
[Fact]
public void RegexMatcher_IsMatch()
{
@@ -65,10 +77,23 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new RegexMatcher("H.*o", true);
// Act
double result = matcher.IsMatch("hello world!");
double result = matcher.IsMatch("hello");
// Assert
Check.That(result).IsEqualTo(1.0d);
}
[Fact]
public void RegexMatcher_IsMatch_RejectOnMatch()
{
// Assign
var matcher = new RegexMatcher(MatchBehaviour.RejectOnMatch, "h.*o");
// Act
double result = matcher.IsMatch("hello");
// Assert
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -13,7 +13,7 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new SimMetricsMatcher("X");
// Act
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("SimMetricsMatcher.Levenstein");
@@ -57,5 +57,31 @@ namespace WireMock.Net.Tests.Matchers
// Assert
Check.That(result).IsStrictlyLessThan(0.1).And.IsStrictlyGreaterThan(0.05);
}
[Fact]
public void SimMetricsMatcher_IsMatch_AcceptOnMatch()
{
// Assign
var matcher = new SimMetricsMatcher("test");
// Act
double result = matcher.IsMatch("test");
// Assert
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void SimMetricsMatcher_IsMatch_RejectOnMatch()
{
// Assign
var matcher = new SimMetricsMatcher(MatchBehaviour.RejectOnMatch, "test");
// Act
double result = matcher.IsMatch("test");
// Assert
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -65,7 +65,7 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new WildcardMatcher("x");
// Act
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("WildcardMatcher");
@@ -83,5 +83,17 @@ namespace WireMock.Net.Tests.Matchers
// Assert
Check.That(patterns).ContainsExactly("x");
}
[Fact]
public void WildcardMatcher_IsMatch_RejectOnMatch()
{
// Assign
var matcher = new WildcardMatcher(MatchBehaviour.RejectOnMatch, "m");
// Act
double result = matcher.IsMatch("m");
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -13,7 +13,7 @@ namespace WireMock.Net.Tests.Matchers
var matcher = new XPathMatcher("X");
// Act
string name = matcher.GetName();
string name = matcher.Name;
// Assert
Check.That(name).Equals("XPathMatcher");
@@ -31,5 +31,39 @@ namespace WireMock.Net.Tests.Matchers
// Assert
Check.That(patterns).ContainsExactly("X");
}
[Fact]
public void XPathMatcher_IsMatch_AcceptOnMatch()
{
// Assign
string xml = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
</todo-list>";
var matcher = new XPathMatcher("/todo-list[count(todo-item) = 1]");
// Act
double result = matcher.IsMatch(xml);
// Assert
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void XPathMatcher_IsMatch_RejectOnMatch()
{
// Assign
string xml = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
</todo-list>";
var matcher = new XPathMatcher(MatchBehaviour.RejectOnMatch, "/todo-list[count(todo-item) = 1]");
// Act
double result = matcher.IsMatch(xml);
// Assert
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -15,10 +15,10 @@ namespace WireMock.Net.Tests
public void Request_WithCookie_OK()
{
// given
var spec = Request.Create().UsingAnyVerb().WithCookie("session", "a*");
var spec = Request.Create().UsingAnyMethod().WithCookie("session", "a*");
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, null, null, null, null, new Dictionary<string, string> { { "session", "abc" } });
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, null, null, new Dictionary<string, string> { { "session", "abc" } });
// then
var requestMatchResult = new RequestMatchResult();

View File

@@ -87,7 +87,34 @@ namespace WireMock.Net.Tests.RequestMatchers
Check.That(score).IsEqualTo(0.0d);
// Verify
stringMatcherMock.Verify(m => m.IsMatch("b"), Times.Never);
stringMatcherMock.Verify(m => m.IsMatch(It.IsAny<string>()), Times.Never);
}
[Fact]
public void RequestMessageBodyMatcher_GetMatchingScore_BodyAsJson_and_BodyAsString_IStringMatcher()
{
// Assign
var body = new BodyData
{
BodyAsJson = new { value = 42 },
BodyAsString = "orig"
};
var stringMatcherMock = new Mock<IStringMatcher>();
stringMatcherMock.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(0.5d);
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", body);
var matcher = new RequestMessageBodyMatcher(stringMatcherMock.Object);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.5d);
// Verify
stringMatcherMock.Verify(m => m.IsMatch(It.IsAny<string>()), Times.Once);
}
[Fact]

View File

@@ -9,6 +9,99 @@ namespace WireMock.Net.Tests.RequestMatchers
{
public class RequestMessageCookieMatcherTests
{
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_AcceptOnMatch_CookieDoesNotExists()
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "c", "x");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_RejectOnMatch_CookieDoesNotExists()
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1");
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "c", "x");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_AcceptOnMatch_CookieDoesNotMatchPattern()
{
// Assign
var cookies = new Dictionary<string, string> { { "c", "x" } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "no-match", "123");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_RejectOnMatch_CookieDoesNotMatchPattern()
{
// Assign
var cookies = new Dictionary<string, string> { { "h", "x" } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "no-match", "123");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_AcceptOnMatch()
{
// Assign
var cookies = new Dictionary<string, string> { { "h", "x" } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.AcceptOnMatch, "h", "x");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_RejectOnMatch()
{
// Assign
var cookies = new Dictionary<string, string> { { "h", "x" } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, null, cookies);
var matcher = new RequestMessageCookieMatcher(MatchBehaviour.RejectOnMatch, "h", "x");
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageCookieMatcher_GetMatchingScore_IStringMatcher_Match()
{

View File

@@ -9,11 +9,104 @@ namespace WireMock.Net.Tests.RequestMatchers
{
public class RequestMessageHeaderMatcherTests
{
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_AcceptOnMatch_HeaderDoesNotExists()
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1");
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, "h", "x", true);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_RejectOnMatch_HeaderDoesNotExists()
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1");
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.RejectOnMatch, "h", "x", true);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_AcceptOnMatch_HeaderDoesNotMatchPattern()
{
// Assign
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, headers);
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, "no-match", "123", true);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_RejectOnMatch_HeaderDoesNotMatchPattern()
{
// Assign
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, headers);
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.RejectOnMatch, "no-match", "123", true);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_AcceptOnMatch()
{
// Assign
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, headers);
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.AcceptOnMatch, "h", "x", true);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(1.0d);
}
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_RejectOnMatch()
{
// Assign
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, headers);
var matcher = new RequestMessageHeaderMatcher(MatchBehaviour.RejectOnMatch, "h", "x", true);
// Act
var result = new RequestMatchResult();
double score = matcher.GetMatchingScore(requestMessage, result);
// Assert
Check.That(score).IsEqualTo(0.0d);
}
[Fact]
public void RequestMessageHeaderMatcher_GetMatchingScore_IStringMatcher_Match()
{
// Assign
var headers = new Dictionary<string, string[]> { { "h", new [] { "x" } } };
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
var requestMessage = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.1", null, headers);
var matcher = new RequestMessageHeaderMatcher("h", new ExactMatcher("x"));

View File

@@ -1,5 +1,6 @@
using System;
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using Xunit;
@@ -12,7 +13,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost?key=test1,test2"), "GET", "127.0.0.1");
var matcher = new RequestMessageParamMatcher("key", new[] { "test1", "test2" });
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", new[] { "test1", "test2" });
// Act
var result = new RequestMatchResult();
@@ -27,7 +28,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost?key=test0,test2"), "GET", "127.0.0.1");
var matcher = new RequestMessageParamMatcher("key", new[] { "test1", "test2" });
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", new[] { "test1", "test2" });
// Act
var result = new RequestMatchResult();
@@ -42,7 +43,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost?key"), "GET", "127.0.0.1");
var matcher = new RequestMessageParamMatcher("key", new[] { "test1", "test2" });
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", new[] { "test1", "test2" });
// Act
var result = new RequestMatchResult();
@@ -57,7 +58,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost?key"), "GET", "127.0.0.1");
var matcher = new RequestMessageParamMatcher("key");
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key");
// Act
var result = new RequestMatchResult();
@@ -72,7 +73,7 @@ namespace WireMock.Net.Tests.RequestMatchers
{
// Assign
var requestMessage = new RequestMessage(new Uri("http://localhost?key"), "GET", "127.0.0.1");
var matcher = new RequestMessageParamMatcher("key", new string[] { });
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", new string[] { });
// Act
var result = new RequestMatchResult();

View File

@@ -5,6 +5,7 @@ using NFluent;
using Xunit;
using WireMock.RequestBuilders;
using WireMock.Matchers.Request;
using WireMock.Util;
namespace WireMock.Net.Tests
{
@@ -30,12 +31,14 @@ namespace WireMock.Net.Tests
public void Should_exclude_requests_not_matching_given_headers()
{
// given
var spec = Request.Create().UsingAnyVerb().WithHeader("X-toto", "tatata");
var spec = Request.Create().UsingAnyMethod().WithHeader("X-toto", "tatata");
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
// then
var requestMatchResult = new RequestMatchResult();
@@ -46,12 +49,14 @@ namespace WireMock.Net.Tests
public void Should_exclude_requests_not_matching_given_headers_ignorecase()
{
// given
var spec = Request.Create().UsingAnyVerb().WithHeader("X-toto", "abc", false);
var spec = Request.Create().UsingAnyMethod().WithHeader("X-toto", "abc", false);
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "ABC" } } });
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "ABC" } } });
// then
var requestMatchResult = new RequestMatchResult();
@@ -62,47 +67,50 @@ namespace WireMock.Net.Tests
public void Should_specify_requests_matching_given_header_prefix()
{
// given
var spec = Request.Create().UsingAnyVerb().WithHeader("X-toto", "tata*");
var spec = Request.Create().UsingAnyMethod().WithHeader("X-toto", "tata*");
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "TaTa" } } });
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "TaTa" } } });
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_body()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody("Hello world!");
var spec = Request.Create().UsingAnyMethod().WithBody("Hello world!");
// when
string bodyAsString = "Hello world!";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "Hello world!"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_exclude_requests_not_matching_given_body()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(" Hello world! ");
var spec = Request.Create().UsingAnyMethod().WithBody(" Hello world! ");
// when
string bodyAsString = "xxx";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
var body = new BodyData
{
BodyAsString = "xxx"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
// then
var requestMatchResult = new RequestMatchResult();
@@ -127,7 +135,7 @@ namespace WireMock.Net.Tests
public void Should_specify_requests_matching_given_param_func()
{
// given
var spec = Request.Create().UsingAnyVerb().WithParam(p => p.ContainsKey("bar"));
var spec = Request.Create().UsingAnyMethod().WithParam(p => p.ContainsKey("bar"));
// when
var request = new RequestMessage(new Uri("http://localhost/foo?bar=1&bar=2"), "PUT", ClientIp);

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using NFluent;
@@ -19,7 +18,7 @@ namespace WireMock.Net.Tests
public void Request_WithBody_FuncString()
{
// Assign
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(b => b.Contains("b"));
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b.Contains("b"));
// Act
var body = new BodyData
@@ -37,7 +36,7 @@ namespace WireMock.Net.Tests
public void Request_WithBody_FuncJson()
{
// Assign
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(b => b != null);
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b != null);
// Act
var body = new BodyData
@@ -55,7 +54,7 @@ namespace WireMock.Net.Tests
public void Request_WithBody_FuncByteArray()
{
// Assign
var requestBuilder = Request.Create().UsingAnyVerb().WithBody((byte[] b) => b != null);
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((byte[] b) => b != null);
// Act
var body = new BodyData
@@ -73,12 +72,14 @@ namespace WireMock.Net.Tests
public void Request_WithBodyExactMatcher()
{
// given
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(new ExactMatcher("cat"));
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(new ExactMatcher("cat"));
// when
string bodyAsString = "cat";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "cat"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
@@ -89,12 +90,14 @@ namespace WireMock.Net.Tests
public void Request_WithBodyWildcardMatcher()
{
// given
var spec = Request.Create().WithPath("/foo").UsingAnyVerb().WithBody(new WildcardMatcher("H*o*"));
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithBody(new WildcardMatcher("H*o*"));
// when
string bodyAsString = "Hello world!";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "tatata" } } });
var body = new BodyData
{
BodyAsString = "Hello world!"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
@@ -105,17 +108,19 @@ namespace WireMock.Net.Tests
public void Request_WithBodyXPathMatcher_true()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 3]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 3]"));
// when
string xmlBodyAsString = @"
var body = new BodyData
{
BodyAsString = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
<todo-item id='a2'>def</todo-item>
<todo-item id='a3'>xyz</todo-item>
</todo-list>";
byte[] body = Encoding.UTF8.GetBytes(xmlBodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, xmlBodyAsString, Encoding.UTF8);
</todo-list>"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
@@ -126,17 +131,19 @@ namespace WireMock.Net.Tests
public void Request_WithBodyXPathMatcher_false()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 99]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 99]"));
// when
string xmlBodyAsString = @"
var body = new BodyData
{
BodyAsString = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
<todo-item id='a2'>def</todo-item>
<todo-item id='a3'>xyz</todo-item>
</todo-list>";
byte[] body = Encoding.UTF8.GetBytes(xmlBodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, xmlBodyAsString, Encoding.UTF8);
</todo-list>"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
@@ -147,12 +154,14 @@ namespace WireMock.Net.Tests
public void Request_WithBodyJsonPathMatcher_true()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
// when
string bodyAsString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
@@ -163,12 +172,14 @@ namespace WireMock.Net.Tests
public void Request_WithBodyJsonPathMatcher_false()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"));
// when
string bodyAsString = "{ \"things\": { \"name\": \"Wiremock\" } }";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "{ \"things\": { \"name\": \"Wiremock\" } }"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
@@ -179,13 +190,14 @@ namespace WireMock.Net.Tests
public void Request_WithBodyAsJson_Object_JsonPathMatcher_true()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
// when
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8
};
@@ -195,17 +207,19 @@ namespace WireMock.Net.Tests
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Array_JsonPathMatcher_1()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$..books[?(@.price < 10)]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..books[?(@.price < 10)]"));
// when
string jsonString = "{ \"books\": [ { \"category\": \"test1\", \"price\": 8.95 }, { \"category\": \"test2\", \"price\": 20 } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8
};
@@ -220,13 +234,14 @@ namespace WireMock.Net.Tests
public void Request_WithBodyAsJson_Array_JsonPathMatcher_2()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$..[?(@.Id == 1)]"));
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..[?(@.Id == 1)]"));
// when
string jsonString = "{ \"Id\": 1, \"Name\": \"Test\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8
};
@@ -243,7 +258,7 @@ namespace WireMock.Net.Tests
{
// Assign
object body = DateTime.MinValue;
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(body);
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
var bodyData = new BodyData
{
@@ -263,7 +278,7 @@ namespace WireMock.Net.Tests
{
// Assign
byte[] body = { 123 };
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(body);
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
var bodyData = new BodyData
{

View File

@@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
using NFluent;
using WireMock.Matchers;
using Xunit;
using WireMock.RequestBuilders;
using WireMock.Matchers.Request;
using WireMock.Util;
namespace WireMock.Net.Tests
{
@@ -17,12 +17,14 @@ namespace WireMock.Net.Tests
public void Request_WithPath_WithHeader_Match()
{
// given
var spec = Request.Create().WithPath("/foo").UsingAnyVerb().WithHeader("X-toto", "tata");
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithHeader("X-toto", "tata");
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
// then
var requestMatchResult = new RequestMatchResult();
@@ -105,9 +107,11 @@ namespace WireMock.Net.Tests
var spec = Request.Create().WithPath("/foo").UsingDelete();
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "Delete", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "Delete", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();

View File

@@ -41,9 +41,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test {{request.url}} {{request.path}} {{request.method}}")
@@ -60,9 +62,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_Handlebars_Query()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
@@ -79,9 +83,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_Handlebars_Header()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
@@ -98,9 +104,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_Handlebars_Headers()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
@@ -118,9 +126,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost:1234"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost:1234"), "POST", ClientIp, body);
var response = Response.Create()
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")

View File

@@ -3,6 +3,7 @@ using System.Text;
using System.Threading.Tasks;
using NFluent;
using WireMock.ResponseBuilders;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.ResponseBuilderTests
@@ -15,9 +16,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_String()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
var response = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.String, Encoding.ASCII);
@@ -34,9 +37,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_Bytes()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
var response = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.SameAsSource, Encoding.ASCII);
@@ -53,9 +58,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_WithBody_String_Encoding()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
var response = Response.Create().WithBody("test", null, Encoding.ASCII);
@@ -71,9 +78,11 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
public async Task Response_ProvideResponse_WithBody_Object_Encoding()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
object x = new { value = "test" };
var response = Response.Create().WithBodyAsJson(x, Encoding.ASCII);
@@ -137,7 +146,7 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
// Assert
Check.That(responseMessage.Body).IsNull();
Check.That(responseMessage.BodyAsBytes).IsNull();
Check.That(((dynamic) responseMessage.BodyAsJson).value).Equals(42);
Check.That(((dynamic)responseMessage.BodyAsJson).value).Equals(42);
Check.That(responseMessage.BodyEncoding).Equals(Encoding.ASCII);
}
}

View File

@@ -9,18 +9,21 @@ namespace WireMock.Net.Tests
{
private const string ClientIp = "::1";
[Fact]
public async void Response_Create_WithHeader_ContentLength()
[Theory]
[InlineData("Content-Length", "1024")]
[InlineData("Transfer-Encoding", "identity")]
[InlineData("Location", "http://test")]
public async void Response_Create_WithHeader(string headerName, string headerValue)
{
// Assign
var requestMock = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp);
IResponseBuilder builder = Response.Create().WithHeader("Content-Length", "1024");
IResponseBuilder builder = Response.Create().WithHeader(headerName, headerValue);
// Act
var response = await builder.ProvideResponseAsync(requestMock);
// Assert
Check.That(response.Headers["Content-Length"].ToString()).Equals("1024");
Check.That(response.Headers[headerName].ToString()).Equals(headerValue);
}
}
}

View File

@@ -47,7 +47,7 @@ namespace WireMock.Net.Tests.Serialization
{
// Assign
var matcherMock = new Mock<IStringMatcher>();
matcherMock.Setup(m => m.GetName()).Returns("test");
matcherMock.Setup(m => m.Name).Returns("test");
matcherMock.Setup(m => m.GetPatterns()).Returns(new[] { "p1", "p2" });
// Act