Compare commits

...

28 Commits

Author SHA1 Message Date
Stef Heyenrath
24d00845fb 1.0.4.2 2018-06-26 23:24:32 +02:00
Stef Heyenrath
4283732b6c Support for string and object in JsonMatcher. (#157)
* JsonMatcher (#154)

* small update in example code
2018-06-26 23:20:30 +02:00
Stef Heyenrath
b2690017a8 Set Microsoft.NET.Test.Sdk back to 15.3.0 2018-06-25 20:29:10 +02:00
Stef Heyenrath
9470130d65 responsebody.json 2018-06-25 20:21:40 +02:00
Stef Heyenrath
b5f0e658da 1.0.4.1 (#153) 2018-06-25 19:57:42 +02:00
Stef Heyenrath
2eff243a96 Added JsonMatcher (#153) 2018-06-25 19:36:41 +02:00
Stef Heyenrath
2895bf2dea Add gitter chat badge 2018-06-24 12:12:43 +02:00
Stef Heyenrath
f61a814ab5 Fix coveralls.net 2018-06-23 16:33:29 +02:00
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
86 changed files with 1983 additions and 797 deletions

View File

@@ -1,3 +1,75 @@
# 1.0.4.2 (26 June 2018)
- [#157](https://github.com/WireMock-Net/WireMock.Net/pull/157) - Support for string and object in JsonMatcher. contributed by Stef Heyenrath ([StefH](https://github.com/StefH)) +feature
- [#155](https://github.com/WireMock-Net/WireMock.Net/pull/155) - Replace JsonMatcher with JsonObjectMatcher and directly support JSON body matching. contributed by ([DavidKorn](https://github.com/DavidKorn))
- [#154](https://github.com/WireMock-Net/WireMock.Net/issues/154) - Feature: support BodyAsJson for Request in static mapping files. +feature
Commits: 9470130d65...4283732b6c
# 1.0.4.1 (25 June 2018)
- [#153](https://github.com/WireMock-Net/WireMock.Net/issues/153) - Feature: Add JsonMatcher to support Json mapping
Commits: f61a814ab5...2eff243a96
# 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.2
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags

View File

@@ -1,9 +1,10 @@
# WireMock.Net
A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) which mimics the functionality from the JAVA based http://WireMock.org
[![Gitter](https://img.shields.io/gitter/room/wiremock_dotnet/Lobby.svg)](https://gitter.im/wiremock_dotnet/Lobby)
[![GitHub issues](https://img.shields.io/github/issues/WireMock-Net/WireMock.Net.svg)](https://github.com/WireMock-Net/WireMock.Net/issues)
[![Build status](https://ci.appveyor.com/api/projects/status/b3n6q3ygbww4lyls?svg=true)](https://ci.appveyor.com/project/StefH/wiremock-net)
[![Coverage Status](https://coveralls.io/repos/github/WireMock-Net/WireMock.Net/badge.svg?branch=master)](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master)
[![GitHub issues](https://img.shields.io/github/issues/WireMock-Net/WireMock.Net.svg)](https://github.com/WireMock-Net/WireMock.Net/issues)
[![GitHub stars](https://img.shields.io/github/stars/WireMock-Net/WireMock.Net.svg)](https://github.com/WireMock-Net/WireMock.Net/stargazers)
| Name | NuGet |

View File

@@ -1,6 +1,6 @@
os: Visual Studio 2017
version: 1.0.2.{build}
version: 1.0.4.{build}
configuration:
- Debug
@@ -35,9 +35,9 @@ build_script:
test_script:
- nuget.exe install OpenCover -ExcludeVersion
- nuget.exe install coveralls.net -ExcludeVersion
- nuget.exe install coveralls.net -ExcludeVersion -Version 0.7.0
- pip install codecov
- cmd: '"OpenCover\tools\OpenCover.Console.exe" -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -output:coverage.xml -returntargetcode -register:user -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -nodefaultfilters -returntargetcode -oldstyle -searchdirs:".\test\WireMock.Net.Tests\bin\%CONFIGURATION%\net452"'
- codecov -f "coverage.xml"
- coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml
- coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml

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));
@@ -35,11 +38,12 @@ namespace WireMock.Net.ConsoleApplication
server.AllowPartialMapping();
// .WithHeader("Stef", "Stef")
//server
// .Given(Request.Create().WithPath("*"))
// .RespondWith(Response.Create()
// .WithProxy("http://restcountries.eu"));
server
.Given(Request.Create()
.WithPath("/xpath").UsingPost()
.WithBody(new XPathMatcher("/todo-list[count(todo-item) = 3]"))
)
.RespondWith(Response.Create().WithBody("XPathMatcher!"));
server
.Given(Request
@@ -50,6 +54,26 @@ namespace WireMock.Net.ConsoleApplication
.RespondWith(Response.Create()
.WithBody(@"{ ""result"": ""JsonPathMatcher !!!""}"));
server
.Given(Request
.Create()
.WithPath("/jsonbodytest1")
.WithBody(new JsonMatcher("{ \"x\": 42, \"s\": \"s\" }"))
.UsingPost())
.WithGuid("debaf408-3b23-4c04-9d18-ef1c020e79f2")
.RespondWith(Response.Create()
.WithBody(@"{ ""result"": ""jsonbodytest1"" }"));
server
.Given(Request
.Create()
.WithPath("/jsonbodytest2")
.WithBody(new JsonMatcher(new { x = 42, s = "s" }))
.UsingPost())
.WithGuid("debaf408-3b23-4c04-9d18-ef1c020e79f3")
.RespondWith(Response.Create()
.WithBody(@"{ ""result"": ""jsonbodytest2"" }"));
server
.Given(Request
.Create()
@@ -63,7 +87,6 @@ namespace WireMock.Net.ConsoleApplication
.Given(Request.Create().WithPath("/headers", "/headers_test").UsingPost().WithHeader("Content-Type", "application/json*"))
.RespondWith(Response.Create()
.WithStatusCode(201)
//.WithHeader("MyHeader", "application/json", "application/json2")
.WithHeader("Content-Type", "application/json")
.WithBodyAsJson(new { result = "data:headers posted with 201" }));
@@ -150,6 +173,26 @@ 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))
@@ -159,7 +202,7 @@ namespace WireMock.Net.ConsoleApplication
.Given(Request.Create().WithPath("/partial").UsingPost().WithBody(new SimMetricsMatcher(new[] { "cat", "dog" })))
.RespondWith(Response.Create().WithStatusCode(200).WithBody("partial = 200"));
// http://localhost:8080/any/any?start=1000&stop=1&stop=2
// http://localhost:8080/trans?start=1000&stop=1&stop=2
server
.Given(Request.Create().WithPath("/trans").UsingGet())
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
@@ -167,6 +210,7 @@ namespace WireMock.Net.ConsoleApplication
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json")
.WithHeader("Transformed-Postman-Token", "token is {{request.headers.Postman-Token}}")
.WithHeader("xyz_{{request.headers.Postman-Token}}", "token is {{request.headers.Postman-Token}}")
.WithBody(@"{""msg"": ""Hello world CATCH-ALL on /*, {{request.path}}, bykey={{request.query.start}}, bykey={{request.query.stop}}, byidx0={{request.query.stop.[0]}}, byidx1={{request.query.stop.[1]}}"" }")
.WithTransformer()
.WithDelay(TimeSpan.FromMilliseconds(100))

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

@@ -42,8 +42,18 @@
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.4\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
@@ -53,6 +63,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="log4net.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.8" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.4" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net452" />
</packages>

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.2</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

View File

@@ -11,18 +11,23 @@
public string Name { get; set; }
/// <summary>
/// Gets or sets the pattern.
/// Gets or sets the pattern. Can be a string (default) or an object;
/// </summary>
public string Pattern { get; set; }
public object Pattern { get; set; }
/// <summary>
/// Gets or sets the patterns.
/// Gets or sets the patterns. Can be array of strings (default) or an array of objects;
/// </summary>
public string[] Patterns { get; set; }
public object[] Patterns { get; set; }
/// <summary>
/// Gets or sets the ignore case.
/// </summary>
public bool? IgnoreCase { get; set; }
/// <summary>
/// Reject on match.
/// </summary>
public bool? RejectOnMatch { get; set; }
}
}

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,10 +1,11 @@
using System.Linq;
using JetBrains.Annotations;
using WireMock.Validation;
namespace WireMock.Matchers
{
/// <summary>
/// ExactMatcher
/// ExactObjectMatcher
/// </summary>
/// <seealso cref="IObjectMatcher" />
public class ExactObjectMatcher : IObjectMatcher
@@ -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.
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> class.
/// </summary>
/// <param name="value">The value.</param>
public ExactObjectMatcher([NotNull] object value)
public ExactObjectMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
{
_object = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// Initializes a new instance of the <see cref="ExactObjectMatcher"/> 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="ExactObjectMatcher"/> 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="ExactObjectMatcher"/> 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,11 @@
/// <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

@@ -0,0 +1,15 @@
namespace WireMock.Matchers
{
/// <summary>
/// IValueMatcher
/// </summary>
/// <seealso cref="IObjectMatcher" />
public interface IValueMatcher: IObjectMatcher
{
/// <summary>
/// Gets the value (can be a string or an obejct).
/// </summary>
/// <returns>Value</returns>
object Value { get; }
}
}

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;
@@ -10,58 +10,74 @@ namespace WireMock.Matchers
/// JsonPathMatcher
/// </summary>
/// <seealso cref="IMatcher" />
/// <seealso cref="IObjectMatcher" />
public class JsonPathMatcher : IStringMatcher, IObjectMatcher
{
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,18 +86,15 @@ 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)
{
// Wrap in array if needed
JToken jarray = jtoken is JArray ? jtoken : new JArray(jtoken);
JToken tokenOrArray = jtoken is JArray ? jtoken : new JArray(jtoken);
return MatchScores.ToScore(_patterns.Select(pattern => jarray.SelectToken(pattern) != null));
return MatchScores.ToScore(_patterns.Select(pattern => tokenOrArray.SelectToken(pattern) != null));
}
}
}

View File

@@ -0,0 +1,92 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Validation;
namespace WireMock.Matchers
{
/// <summary>
/// JsonMatcher
/// </summary>
public class JsonMatcher : IValueMatcher
{
/// <inheritdoc cref="IValueMatcher.Value"/>
public object Value { get; }
/// <inheritdoc cref="IMatcher.Name"/>
public string Name => "JsonMatcher";
/// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="value">The string value to check for equality.</param>
public JsonMatcher([NotNull] string value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="value">The object value to check for equality.</param>
public JsonMatcher([NotNull] object value) : this(MatchBehaviour.AcceptOnMatch, value)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The string value to check for equality.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] string value)
{
Check.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour;
Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The object value to check for equality.</param>
public JsonMatcher(MatchBehaviour matchBehaviour, [NotNull] object value)
{
Check.NotNull(value, nameof(value));
MatchBehaviour = matchBehaviour;
Value = value;
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
{
bool match = false;
if (input != null)
{
try
{
// Check if JToken or object
JToken jtokenInput = input is JToken tokenInput ? tokenInput : JObject.FromObject(input);
// Check if JToken or string or object
JToken jtokenValue =
Value is JToken tokenValue ? tokenValue :
Value is string stringValue ? JToken.Parse(stringValue) :
JObject.FromObject(input);
match = JToken.DeepEquals(jtokenValue, jtokenInput);
}
catch (JsonException)
{
// just ignore JsonException
}
}
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
}
}
}

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

@@ -116,7 +116,7 @@ namespace WireMock.Serialization
mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyAsFileIsCached;
mappingModel.Response.UseTransformer = response.UseTransformer;
if (response.ResponseMessage.BodyEncoding != null)
if (response.ResponseMessage.BodyEncoding != null && response.ResponseMessage.BodyEncoding.WebName != "utf-8")
{
mappingModel.Response.BodyEncoding = new EncodingModel
{
@@ -132,7 +132,7 @@ namespace WireMock.Serialization
private static IDictionary<string, object> Map(IDictionary<string, WireMockList<string>> dictionary)
{
if (dictionary == null)
if (dictionary == null || dictionary.Count == 0)
{
return null;
}

View File

@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using SimMetrics.Net;
using WireMock.Admin.Mappings;
using WireMock.Matchers;
@@ -8,6 +10,54 @@ namespace WireMock.Serialization
{
internal static class MatcherMapper
{
public static IMatcher Map([CanBeNull] MatcherModel matcher)
{
if (matcher == null)
{
return null;
}
string[] parts = matcher.Name.Split('.');
string matcherName = parts[0];
string matcherType = parts.Length > 1 ? parts[1] : null;
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new [] { matcher.Pattern as string };
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
switch (matcherName)
{
case "ExactMatcher":
return new ExactMatcher(matchBehaviour, stringPatterns);
case "RegexMatcher":
return new RegexMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
case "JsonMatcher":
return new JsonMatcher(matchBehaviour, matcher.Pattern);
case "JsonPathMatcher":
return new JsonPathMatcher(matchBehaviour, stringPatterns);
case "XPathMatcher":
return new XPathMatcher(matchBehaviour, (string) matcher.Pattern);
case "WildcardMatcher":
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
case "SimMetricsMatcher":
SimMetricType type = SimMetricType.Levenstein;
if (!string.IsNullOrEmpty(matcherType) && !Enum.TryParse(matcherType, out type))
{
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
}
return new SimMetricsMatcher(matchBehaviour, (string) matcher.Pattern, type);
default:
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
}
}
public static MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
{
return matchers?.Select(Map).Where(x => x != null).ToArray();
@@ -20,13 +70,21 @@ namespace WireMock.Serialization
return null;
}
string[] patterns = matcher is IStringMatcher stringMatcher ? stringMatcher.GetPatterns() : new string[0];
// If the matcher is a IStringMatcher, get the patterns.
// If the matcher is a IValueMatcher, get the value (can be string or object).
// Else empty array
object[] patterns = matcher is IStringMatcher stringMatcher ?
stringMatcher.GetPatterns().Cast<object>().ToArray() :
matcher is IValueMatcher valueMatcher ? new[] { valueMatcher.Value } :
new object[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

@@ -1,55 +0,0 @@
using System;
using JetBrains.Annotations;
using SimMetrics.Net;
using WireMock.Admin.Mappings;
using WireMock.Matchers;
namespace WireMock.Serialization
{
internal static class MatcherModelMapper
{
public static IMatcher Map([CanBeNull] MatcherModel matcher)
{
if (matcher == null)
{
return null;
}
string[] parts = matcher.Name.Split('.');
string matcherName = parts[0];
string matcherType = parts.Length > 1 ? parts[1] : null;
string[] patterns = matcher.Patterns ?? new[] { matcher.Pattern };
switch (matcherName)
{
case "ExactMatcher":
return new ExactMatcher(patterns);
case "RegexMatcher":
return new RegexMatcher(patterns, matcher.IgnoreCase == true);
case "JsonPathMatcher":
return new JsonPathMatcher(patterns);
case "XPathMatcher":
return new XPathMatcher(matcher.Pattern);
case "WildcardMatcher":
return new WildcardMatcher(patterns, matcher.IgnoreCase == true);
case "SimMetricsMatcher":
SimMetricType type = SimMetricType.Levenstein;
if (!string.IsNullOrEmpty(matcherType) && !Enum.TryParse(matcherType, out type))
{
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
}
return new SimMetricsMatcher(matcher.Pattern, type);
default:
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
}
}
}
}

View File

@@ -9,7 +9,6 @@ using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WireMock.Admin.Mappings;
using WireMock.Admin.Requests;
using WireMock.Admin.Settings;
using WireMock.Http;
using WireMock.Logging;
@@ -36,8 +35,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 +49,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 +195,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 +209,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 +224,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));
@@ -239,9 +238,13 @@ namespace WireMock.Server
}
});
if (requestMessage.Body != null)
if (requestMessage.BodyAsJson != null)
{
request.WithBody(new ExactMatcher(requestMessage.Body));
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));
}
else if (requestMessage.Body != null)
{
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
}
var response = Response.Create(responseMessage);
@@ -457,7 +460,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 +481,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 +511,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 +520,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,
@@ -609,7 +552,7 @@ namespace WireMock.Server
var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);
if (clientIPModel?.Matchers != null)
{
requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MatcherModelMapper.Map).Cast<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
}
}
}
@@ -625,7 +568,7 @@ namespace WireMock.Server
var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
if (pathModel?.Matchers != null)
{
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherModelMapper.Map).Cast<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
}
}
}
@@ -641,21 +584,21 @@ namespace WireMock.Server
var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
if (urlModel?.Matchers != null)
{
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherModelMapper.Map).Cast<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
}
}
}
if (requestModel.Methods != null)
{
requestBuilder = requestBuilder.UsingVerb(requestModel.Methods);
requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);
}
if (requestModel.Headers != null)
{
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
{
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MatcherModelMapper.Map).Cast<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
}
}
@@ -663,7 +606,7 @@ namespace WireMock.Server
{
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
{
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MatcherModelMapper.Map).Cast<IStringMatcher>().ToArray());
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
}
}
@@ -677,7 +620,7 @@ namespace WireMock.Server
if (requestModel.Body?.Matcher != null)
{
var bodyMatcher = MatcherModelMapper.Map(requestModel.Body.Matcher);
var bodyMatcher = MatcherMapper.Map(requestModel.Body.Matcher);
requestBuilder = requestBuilder.WithBody(bodyMatcher);
}

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.2</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()
@@ -85,7 +88,7 @@ namespace WireMock.Net.Tests
string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
string json = File.ReadAllText(folder);
string responseBodyFilePath = Path.Combine(GetCurrentFolder(), "ResponseBodyFiles", "responsebody.json");
string responseBodyFilePath = Path.Combine(GetCurrentFolder(), "responsebody.json");
dynamic jsonObj = JsonConvert.DeserializeObject(json);
jsonObj["Response"]["BodyAsFile"] = responseBodyFilePath;
@@ -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 = new { x = 500, s = "s" };
// Act
var matcher = new ExactObjectMatcher(obj);
double result = matcher.IsMatch(new { x = 500, s = "s" });
// Assert
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void ExactObjectMatcher_IsMatch_RejectOnMatch()
{
// Assign
object obj = new { x = 500, s = "s" };
// Act
var matcher = new ExactObjectMatcher(MatchBehaviour.RejectOnMatch, obj);
double result = matcher.IsMatch(new { x = 500, s = "s" });
// Assert
Check.That(result).IsEqualTo(0.0);
}
}
}

View File

@@ -0,0 +1,132 @@
using Newtonsoft.Json.Linq;
using NFluent;
using WireMock.Matchers;
using Xunit;
namespace WireMock.Net.Tests.Matchers
{
public class JsonMatcherTests
{
[Fact]
public void JsonMatcher_GetName()
{
// Assign
var matcher = new JsonMatcher("{}");
// Act
string name = matcher.Name;
// Assert
Check.That(name).Equals("JsonMatcher");
}
[Fact]
public void JsonMatcher_GetValue()
{
// Assign
var matcher = new JsonMatcher("{}");
// Act
object value = matcher.Value;
// Assert
Check.That(value).Equals("{}");
}
[Fact]
public void JsonMatcher_IsMatch_NullString()
{
// Assign
string s = null;
var matcher = new JsonMatcher("");
// Act
double match = matcher.IsMatch(s);
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonMatcher_IsMatch_NullObject()
{
// Assign
object o = null;
var matcher = new JsonMatcher("");
// Act
double match = matcher.IsMatch(o);
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonMatcher_IsMatch_JObject1()
{
// Assign
var matcher = new JsonMatcher(new { Id = 1, Name = "test" });
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonMatcher_IsMatch_JObject2()
{
// Assign
var matcher = new JsonMatcher(new { Id = 1, Name = "test" });
// Act
var jobject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonMatcher_IsMatch_JObjectAsString()
{
// Assign
var matcher = new JsonMatcher("{ \"Id\" : 1, \"Name\" : \"Test\" }");
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonMatcher_IsMatch_JObjectAsString_RejectOnMatch()
{
// Assign
var matcher = new JsonMatcher(MatchBehaviour.RejectOnMatch, "{ \"Id\" : 1, \"Name\" : \"Test\" }");
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(0.0, match);
}
}
}

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

View File

@@ -13,7 +13,7 @@ namespace WireMock.Net.Tests.Serialization
public void MatcherModelMapper_Map_Null()
{
// Act
IMatcher matcher = MatcherModelMapper.Map(null);
IMatcher matcher = MatcherMapper.Map((MatcherModel)null);
// Assert
Check.That(matcher).IsNull();
@@ -30,7 +30,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
var matcher = (ExactMatcher)MatcherModelMapper.Map(model);
var matcher = (ExactMatcher)MatcherMapper.Map(model);
// Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x");
@@ -47,7 +47,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
var matcher = (ExactMatcher)MatcherModelMapper.Map(model);
var matcher = (ExactMatcher)MatcherMapper.Map(model);
// Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
@@ -65,7 +65,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
var matcher = (RegexMatcher)MatcherModelMapper.Map(model);
var matcher = (RegexMatcher)MatcherMapper.Map(model);
// Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
@@ -84,7 +84,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
var matcher = (WildcardMatcher)MatcherModelMapper.Map(model);
var matcher = (WildcardMatcher)MatcherMapper.Map(model);
// Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
@@ -102,7 +102,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
var matcher = (SimMetricsMatcher)MatcherModelMapper.Map(model);
var matcher = (SimMetricsMatcher)MatcherMapper.Map(model);
// Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x");
@@ -119,7 +119,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
var matcher = (SimMetricsMatcher)MatcherModelMapper.Map(model);
var matcher = (SimMetricsMatcher)MatcherMapper.Map(model);
// Assert
Check.That(matcher.GetPatterns()).ContainsExactly("x");
@@ -136,7 +136,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
Check.ThatCode(() => MatcherModelMapper.Map(model)).Throws<NotSupportedException>();
Check.ThatCode(() => MatcherMapper.Map(model)).Throws<NotSupportedException>();
}
[Fact]
@@ -150,7 +150,7 @@ namespace WireMock.Net.Tests.Serialization
};
// Act
Check.ThatCode(() => MatcherModelMapper.Map(model)).Throws<NotSupportedException>();
Check.ThatCode(() => MatcherMapper.Map(model)).Throws<NotSupportedException>();
}
}
}

View File

@@ -16,23 +16,23 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="3.1.0" />
<PackageReference Include="Moq" Version="4.8.2" />
<PackageReference Include="Moq" Version="4.8.3" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NFluent" Version="2.2.0" />
<PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="3.1.2" />
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
<PackageReference Include="System.Threading" Version="4.3.0" />
<PackageReference Include="xunit" Version="2.3.0-beta1-build3642" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta1-build1309" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net452' ">
</ItemGroup>
<ItemGroup>
<None Update="ResponseBodyFiles\responsebody.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<None Update="responsebody.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="__admin\mappings\00000002-ee28-4f29-ae63-1ac9b0802d86.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>