Compare commits

..

17 Commits

Author SHA1 Message Date
Stef Heyenrath
8d109c69eb Fix #104 2018-03-09 08:20:48 +01:00
Stef Heyenrath
3e634c2fde Example : WireMock.Net.StandAlone.Net461 (#104) 2018-03-08 18:28:53 +01:00
Stef Heyenrath
9b5a482b8d Also handle application/x-www-form-urlencoded as string body 2018-03-08 11:00:19 +01:00
Stef Heyenrath
e18fffb661 release notes 2018-03-04 11:30:50 +01:00
Stef Heyenrath
a2df91a2a2 1.0.3.4 2018-03-04 10:50:30 +01:00
Stef Heyenrath
1442e874cf Remove codecov.io 2018-03-04 10:34:07 +01:00
Alastair Crabtree
3f2c139f90 feat: add WithBody(req => dostuff) style callback (#102) 2018-03-03 08:38:03 +00:00
Stef Heyenrath
2b8a58c68c #100 2018-03-02 14:35:10 +01:00
Stef Heyenrath
977d91109e ICallbackResponseBuilder + added more unit-tests (#101)
* Callback

* Add more tests
2018-03-02 09:12:36 +00:00
Stef Heyenrath
22298114d7 Fix ResponseMessageTransformer 2018-02-28 18:05:10 +01:00
Stef Heyenrath
0be8ee1174 Fix ResponseMessageTransformer (BodyAsJson) 2018-02-28 09:24:27 +01:00
Stef Heyenrath
17741cbc50 FIx for IsStarted (#93) 2018-02-28 08:34:57 +01:00
Stef Heyenrath
938d3fb095 Replace log4net by custom logger (#94) (#96)
* Replace log4net by custom logger

* WireMockNullLogger
2018-02-28 07:01:03 +00:00
Stef Heyenrath
e850126184 Unittest fix (#95)
* fix tests

* fix tests
2018-02-27 11:17:36 +00:00
Stef Heyenrath
ad6c59e3b5 1.0.3.3 2018-02-24 09:04:21 +01:00
Stef Heyenrath
0c25b2e9f2 Json fixes (#91) (#92)
* Fixes for JsonPath

* More tests

* Fixes + added tests
2018-02-23 12:29:43 +00:00
Stef Heyenrath
1ffd56701c fix unit-test 2018-02-14 20:38:19 +01:00
75 changed files with 1402 additions and 478 deletions

View File

@@ -1,3 +1,34 @@
# 1.0.3.7 (09 March 2018)
- [#104](https://github.com/WireMock-Net/WireMock.Net/issues/104) - Issue: PlatformNotSupportedException
Commits: 3e634c2fde...3e634c2fde
# 1.0.3.4 (04 March 2018)
- [#102](https://github.com/WireMock-Net/WireMock.Net/pull/102) - Feature: add WithBody(req => dostuff) style callback contributed by Alastair Crabtree ([alastairtree](https://github.com/alastairtree)) +feature
- [#101](https://github.com/WireMock-Net/WireMock.Net/pull/101) - ICallbackResponseBuilder + added more unit-tests contributed by Stef Heyenrath ([StefH](https://github.com/StefH)) +fix
- [#100](https://github.com/WireMock-Net/WireMock.Net/issues/100) - Question: JsonPathMatcher - not working for rootless jsons?
- [#99](https://github.com/WireMock-Net/WireMock.Net/pull/99) - feat: simple implementation/spike of dynamic responses using callbacks contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#98](https://github.com/WireMock-Net/WireMock.Net/issues/98) - IBodyResponseBuilder.WithBody* should receive the request as a parameter
- [#96](https://github.com/WireMock-Net/WireMock.Net/pull/96) - Replace log4net by custom logger (#94) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#95](https://github.com/WireMock-Net/WireMock.Net/pull/95) - Unittest fix contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#94](https://github.com/WireMock-Net/WireMock.Net/issues/94) - Issue: Introduced dependency on log4net
- [#93](https://github.com/WireMock-Net/WireMock.Net/issues/93) - Bug: FluentMockServer IsStarted after calling Start()
- [#66](https://github.com/WireMock-Net/WireMock.Net/issues/66) - Interested in callbacks?
Commits: e850126184...a2df91a2a2
# 1.0.3.3 (24 February 2018)
- [#92](https://github.com/WireMock-Net/WireMock.Net/pull/92) - Json fixes (#91) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#91](https://github.com/WireMock-Net/WireMock.Net/issues/91) - Bug: WireMock.Net is not matching application/json http requests using JSONPathMatcher +fix
Commits: 1ffd56701c...ad6c59e3b5
# 1.0.3.2 (14 February 2018)
- [#90](https://github.com/WireMock-Net/WireMock.Net/pull/90) - Concurrent issue (#88) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
@@ -5,18 +36,10 @@
- [#88](https://github.com/WireMock-Net/WireMock.Net/issues/88) - Bug: Standalone server throws 500 error when receiving concurrent requests +fix
- [#87](https://github.com/WireMock-Net/WireMock.Net/issues/87) - Feature: Add logging
Commits: 51070dab63...693778659e
Commits: 51070dab63...4f87146622
# 1.0.3.1 (14 February 2018)
- [#89](https://github.com/WireMock-Net/WireMock.Net/pull/89) - Add log4net logging contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
- [#87](https://github.com/WireMock-Net/WireMock.Net/issues/87) - Feature: Add logging
Commits: ...
# 1.0.3 (04 February 2018)
# 1.0.3.0 (05 February 2018)
- [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files +feature
- [#85](https://github.com/WireMock-Net/WireMock.Net/issues/85) - Bug: https for netstandard does not work ? +fix
@@ -25,7 +48,7 @@ Commits: ...
- [#81](https://github.com/WireMock-Net/WireMock.Net/issues/81) - Feature: When using proxy, only BodyAsBytes in case of binary data?
- [#80](https://github.com/WireMock-Net/WireMock.Net/issues/80) - Feature: When using proxy, in case Content-Type is JSON, use BodyAsJson in Response
Commits: 40ff8514ac...cf4e83b10b
Commits: 40ff8514ac...9778c5adbe
# 1.0.2.13 (23 January 2018)

Binary file not shown.

View File

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

View File

@@ -2,7 +2,6 @@
A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) which mimics the functionality from the JAVA based http://WireMock.org
[![Build status](https://ci.appveyor.com/api/projects/status/b3n6q3ygbww4lyls?svg=true)](https://ci.appveyor.com/project/StefH/wiremock-net)
[![codecov](https://codecov.io/gh/WireMock-Net/WireMock.Net/branch/master/graph/badge.svg)](https://codecov.io/gh/WireMock-Net/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)

View File

@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF242EDF-7133-4277-9A0C-18744DE08707}"
EndProject
@@ -46,6 +46,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Proxy.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.Proxy.NETCoreApp2", "examples\WireMock.Net.Console.Proxy.NETCoreApp2\WireMock.Net.Console.Proxy.NETCoreApp2.csproj", "{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.StandAlone.Net461", "examples\WireMock.Net.StandAlone.Net461\WireMock.Net.StandAlone.Net461.csproj", "{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -100,6 +102,10 @@ Global
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6}.Release|Any CPU.Build.0 = Release|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -117,6 +123,7 @@ Global
{049539C1-7A66-4559-AD7A-B1C73B97CBB0} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{26433A8F-BF01-4962-97EB-81BFFBB61096} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{23A9AA3C-40FC-42AA-8A5E-05899795A1C6} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}

View File

@@ -41,6 +41,15 @@ namespace WireMock.Net.ConsoleApplication
// .RespondWith(Response.Create()
// .WithProxy("http://restcountries.eu"));
server
.Given(Request
.Create()
.WithPath("/jsonthings")
.WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"))
.UsingPut())
.RespondWith(Response.Create()
.WithBody(@"{ ""result"": ""JsonPathMatcher !!!""}"));
server
.Given(Request
.Create()

View File

@@ -21,7 +21,7 @@ namespace WireMock.Net.StandAlone.NETCoreApp
{
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
_server = StandAloneApp.Start(args);
_server = StandAloneApp.Start(args, new WireMockLog4NetLogger());
Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down");
@@ -37,7 +37,7 @@ namespace WireMock.Net.StandAlone.NETCoreApp
while (true)
{
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server running");
Console.WriteLine($"{DateTime.UtcNow} WireMock.Net server running : {_server.IsStarted}");
Thread.Sleep(sleepTime);
}
}

View File

@@ -0,0 +1,30 @@
using log4net;
using WireMock.Logging;
namespace WireMock.Net.StandAlone.NETCoreApp
{
internal class WireMockLog4NetLogger : IWireMockLogger
{
private static readonly ILog Log = LogManager.GetLogger(typeof(Program));
public void Debug(string formatString, params object[] args)
{
Log.DebugFormat(formatString, args);
}
public void Info(string formatString, params object[] args)
{
Log.InfoFormat(formatString, args);
}
public void Warn(string formatString, params object[] args)
{
Log.WarnFormat(formatString, args);
}
public void Error(string formatString, params object[] args)
{
Log.ErrorFormat(formatString, args);
}
}
}

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<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>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.1.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Security.Cryptography.X509Certificates" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Win32.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -0,0 +1,19 @@
using System;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
namespace WireMock.Net.StandAlone.Net461
{
static class Program
{
static void Main(string[] args)
{
var server = StandAloneApp.Start(args);
server.Given(Request.Create())
.RespondWith(Response.Create().WithProxy("http://10.10.66.65"));
Console.WriteLine("Press any key to stop the server");
Console.ReadKey();
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WireMock.Net.StandAlone.Net461")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WireMock.Net.StandAlone.Net461")]
[assembly: AssemblyCopyright("Copyright © Stef Heyenrath")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("3c279524-db73-4de3-bef1-f2b2958c9f65")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3C279524-DB73-4DE3-BEF1-F2B2958C9F65}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>WireMock.Net.StandAlone.Net461</RootNamespace>
<AssemblyName>WireMock.Net.StandAlone.Net461</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>WireMock.Net.StandAlone.Net461.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Handlebars, Version=1.8.1.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.1.9.0\lib\net40\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.4.0.0\lib\net451\Microsoft.Owin.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="Microsoft.Owin.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Hosting.4.0.0\lib\net451\Microsoft.Owin.Hosting.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="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="RestEase, Version=1.4.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\RestEase.1.4.4\lib\net45\RestEase.dll</HintPath>
</Reference>
<Reference Include="SimMetrics.Net, Version=1.0.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimMetrics.Net.1.0.4\lib\net45\SimMetrics.Net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Net.Http, Version=4.1.1.2, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Net.Http.4.3.3\lib\net46\System.Net.Http.dll</HintPath>
</Reference>
<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.Net.Http.WebRequest" />
<Reference Include="System.Numerics" />
<Reference Include="System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net461\System.Security.Cryptography.Algorithms.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll</HintPath>
</Reference>
<Reference Include="System.Web" />
<Reference Include="System.Web.Http, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.4\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http.Owin, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Owin.5.2.4\lib\net45\System.Web.Http.Owin.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WireMock.Net, Version=1.0.3.6, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\WireMock.Net.1.0.3.6\lib\net46\WireMock.Net.dll</HintPath>
</Reference>
<Reference Include="WireMock.Net.StandAlone, Version=1.0.3.6, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\WireMock.Net.StandAlone.1.0.3.6\lib\net46\WireMock.Net.StandAlone.dll</HintPath>
</Reference>
<Reference Include="XPath2, Version=1.0.5.1, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\XPath2.1.0.5.1\lib\net40\XPath2.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Handlebars.Net" version="1.9.0" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.4" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.4" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.4" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.4" targetFramework="net461" />
<package id="Microsoft.Owin" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Owin.Hosting" version="4.0.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
<package id="Owin" version="1.0" targetFramework="net461" />
<package id="RestEase" version="1.4.4" targetFramework="net461" />
<package id="SimMetrics.Net" version="1.0.4" targetFramework="net461" />
<package id="System.Net.Http" version="4.3.3" targetFramework="net461" />
<package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
<package id="WireMock.Net" version="1.0.3.6" targetFramework="net461" />
<package id="WireMock.Net.StandAlone" version="1.0.3.6" targetFramework="net461" />
<package id="XPath2" version="1.0.5.1" targetFramework="net461" />
</packages>

View File

@@ -3,7 +3,7 @@ using WireMock.Server;
using WireMock.Settings;
using WireMock.Validation;
using JetBrains.Annotations;
using log4net;
using WireMock.Logging;
namespace WireMock.Net.StandAlone
{
@@ -12,8 +12,6 @@ namespace WireMock.Net.StandAlone
/// </summary>
public static class StandAloneApp
{
private static readonly ILog Log = LogManager.GetLogger(typeof(StandAloneApp));
/// <summary>
/// Start WireMock.Net standalone Server based on the FluentMockServerSettings.
/// </summary>
@@ -30,13 +28,12 @@ namespace WireMock.Net.StandAlone
/// Start WireMock.Net standalone Server based on the commandline arguments.
/// </summary>
/// <param name="args">The commandline arguments</param>
/// <param name="logger">The logger</param>
[PublicAPI]
public static FluentMockServer Start([NotNull] string[] args)
public static FluentMockServer Start([NotNull] string[] args, [CanBeNull] IWireMockLogger logger = null)
{
Check.NotNull(args, nameof(args));
Log.DebugFormat("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
var parser = new SimpleCommandLineParser();
parser.Parse(args);
@@ -52,6 +49,11 @@ namespace WireMock.Net.StandAlone
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
};
if (logger != null)
{
settings.Logger = logger;
}
if (parser.Contains("Port"))
{
settings.Port = parser.GetIntValue("Port");
@@ -74,9 +76,11 @@ namespace WireMock.Net.StandAlone
};
}
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
FluentMockServer server = Start(settings);
Log.InfoFormat("WireMock.Net server listening at {0}", string.Join(",", server.Urls));
settings.Logger.Info("WireMock.Net server listening at {0}", string.Join(",", server.Urls));
return server;
}

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Version>1.0.3.2</Version>
<Version>1.0.3.7</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@@ -36,7 +36,6 @@
<PackageReference Include="JetBrains.Annotations" Version="10.4.0">
<PrivateAssets>All</PrivateAssets>
</PackageReference>
<PackageReference Include="log4net" Version="2.0.8" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,62 +0,0 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Validation;
using WireMock.Settings;
namespace WireMock
{
internal class DynamicResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, ResponseMessage> _responseMessageFunc;
public DynamicResponseProvider([NotNull] Func<RequestMessage, ResponseMessage> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
_responseMessageFunc = responseMessageFunc;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
{
return Task.FromResult(_responseMessageFunc(requestMessage));
}
}
internal class DynamicAsyncResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, Task<ResponseMessage>> _responseMessageFunc;
public DynamicAsyncResponseProvider([NotNull] Func<RequestMessage, Task<ResponseMessage>> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
_responseMessageFunc = responseMessageFunc;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
{
return _responseMessageFunc(requestMessage);
}
}
internal class ProxyAsyncResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> _responseMessageFunc;
private readonly IProxyAndRecordSettings _settings;
public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> responseMessageFunc, [NotNull] IProxyAndRecordSettings settings)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
Check.NotNull(settings, nameof(settings));
_responseMessageFunc = responseMessageFunc;
_settings = settings;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
{
return _responseMessageFunc(requestMessage, _settings);
}
}
}

View File

@@ -16,7 +16,7 @@ namespace WireMock.Http
{
public static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)
{
#if NETSTANDARD || NET46
#if NETSTANDARD
var handler = new HttpClientHandler
{
CheckCertificateRevocationList = false,
@@ -24,12 +24,20 @@ namespace WireMock.Http
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
#elif NET46
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
#else
var handler = new WebRequestHandler
{
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
#endif
if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))

View File

@@ -0,0 +1,47 @@
using JetBrains.Annotations;
namespace WireMock.Logging
{
/// <summary>
/// IWireMockLogger interface
/// </summary>
[PublicAPI]
public interface IWireMockLogger
{
/// <summary>
/// Writes the message at the Debug level using the specified parameters.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param>
[PublicAPI]
[StringFormatMethod("formatString")]
void Debug([NotNull] string formatString, [NotNull] params object[] args);
/// <summary>
/// Writes the message at the Info level using the specified parameters.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param>
[PublicAPI]
[StringFormatMethod("formatString")]
void Info([NotNull] string formatString, [NotNull] params object[] args);
/// <summary>
/// Writes the message at the Warning level using the specified parameters.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param>
[PublicAPI]
[StringFormatMethod("formatString")]
void Warn([NotNull] string formatString, [NotNull] params object[] args);
/// <summary>
/// Writes the message at the Error level using the specified parameters.
/// </summary>
/// <param name="formatString">The format string.</param>
/// <param name="args">The arguments.</param>
[PublicAPI]
[StringFormatMethod("formatString")]
void Error([NotNull] string formatString, [NotNull] params object[] args);
}
}

View File

@@ -0,0 +1,42 @@
using System;
namespace WireMock.Logging
{
/// <summary>
/// WireMockConsoleLogger which logs to Console
/// </summary>
/// <seealso cref="IWireMockLogger" />
public class WireMockConsoleLogger : IWireMockLogger
{
/// <see cref="IWireMockLogger.Debug"/>
public void Debug(string formatString, params object[] args)
{
Console.WriteLine(Format("Debug", formatString, args));
}
/// <see cref="IWireMockLogger.Info"/>
public void Info(string formatString, params object[] args)
{
Console.WriteLine(Format("Info", formatString, args));
}
/// <see cref="IWireMockLogger.Warn"/>
public void Warn(string formatString, params object[] args)
{
Console.WriteLine(Format("Warn", formatString, args));
}
/// <see cref="IWireMockLogger.Error"/>
public void Error(string formatString, params object[] args)
{
Console.WriteLine(Format("Error", formatString, args));
}
private static string Format(string level, string formatString, params object[] args)
{
string message = string.Format(formatString, args);
return $"{DateTime.UtcNow} [{level}] : {message}";
}
}
}

View File

@@ -0,0 +1,29 @@
namespace WireMock.Logging
{
/// <summary>
/// WireMockNullLogger which does not log.
/// </summary>
/// <seealso cref="IWireMockLogger" />
public class WireMockNullLogger : IWireMockLogger
{
/// <see cref="IWireMockLogger.Debug"/>
public void Debug(string formatString, params object[] args)
{
}
/// <see cref="IWireMockLogger.Info"/>
public void Info(string formatString, params object[] args)
{
}
/// <see cref="IWireMockLogger.Warn"/>
public void Warn(string formatString, params object[] args)
{
}
/// <see cref="IWireMockLogger.Error"/>
public void Error(string formatString, params object[] args)
{
}
}
}

View File

@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Matchers.Request;
using WireMock.ResponseProviders;
namespace WireMock
{

View File

@@ -7,8 +7,8 @@ namespace WireMock.Matchers
/// <summary>
/// ExactMatcher
/// </summary>
/// <seealso cref="IMatcher" />
public class ExactMatcher : IMatcher
/// <seealso cref="IStringMatcher" />
public class ExactMatcher : IStringMatcher
{
private readonly string[] _values;
@@ -23,29 +23,19 @@ namespace WireMock.Matchers
_values = values;
}
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
return MatchScores.ToScore(_values.Select(value => value.Equals(input)));
}
/// <summary>
/// Gets the value.
/// </summary>
/// <returns>Patterns</returns>
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public string[] GetPatterns()
{
return _values;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>Name</returns>
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "ExactMatcher";

View File

@@ -0,0 +1,46 @@
using System.Linq;
using JetBrains.Annotations;
namespace WireMock.Matchers
{
/// <summary>
/// ExactMatcher
/// </summary>
/// <seealso cref="IObjectMatcher" />
public class ExactObjectMatcher : IObjectMatcher
{
private readonly object _object;
private readonly byte[] _bytes;
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="value">The value.</param>
public ExactObjectMatcher([NotNull] object value)
{
_object = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="ExactMatcher"/> class.
/// </summary>
/// <param name="value">The value.</param>
public ExactObjectMatcher([NotNull] byte[] value)
{
_bytes = value;
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
{
bool equals = _object != null ? Equals(_object, input) : _bytes.SequenceEqual((byte[])input);
return MatchScores.ToScore(equals);
}
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "ExactObjectMatcher";
}
}
}

View File

@@ -5,19 +5,6 @@
/// </summary>
public interface IMatcher
{
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
double IsMatch(string input);
/// <summary>
/// Gets the patterns.
/// </summary>
/// <returns>Patterns</returns>
string[] GetPatterns();
/// <summary>
/// Gets the name.
/// </summary>

View File

@@ -0,0 +1,15 @@
namespace WireMock.Matchers
{
/// <summary>
/// IObjectMatcher
/// </summary>
public interface IObjectMatcher : IMatcher
{
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
double IsMatch(object input);
}
}

View File

@@ -0,0 +1,21 @@
namespace WireMock.Matchers
{
/// <summary>
/// IStringMatcher
/// </summary>
public interface IStringMatcher : IMatcher
{
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
double IsMatch(string input);
/// <summary>
/// Gets the patterns.
/// </summary>
/// <returns>Patterns</returns>
string[] GetPatterns();
}
}

View File

@@ -10,8 +10,9 @@ namespace WireMock.Matchers
/// JSONPathMatcher
/// </summary>
/// <seealso cref="IMatcher" />
public class JsonPathMatcher : IMatcher
public class JsonPathMatcher : IStringMatcher, IObjectMatcher
{
// private readonly object _jsonPattern;
private readonly string[] _patterns;
/// <summary>
@@ -25,15 +26,20 @@ namespace WireMock.Matchers
_patterns = patterns;
}
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input string</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
//public JsonPathMatcher([NotNull] object jsonPattern)
//{
// Check.NotNull(jsonPattern, nameof(jsonPattern));
// _jsonPattern = jsonPattern;
//}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
if (input == null)
{
return MatchScores.Mismatch;
}
try
{
@@ -47,19 +53,33 @@ namespace WireMock.Matchers
}
}
/// <summary>
/// Gets the patterns.
/// </summary>
/// <returns>Pattern</returns>
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
public double IsMatch(object input)
{
if (input == null)
{
return MatchScores.Mismatch;
}
try
{
var o = input as JObject ?? JObject.FromObject(input);
return MatchScores.ToScore(_patterns.Select(p => o.SelectToken(p) != null));
}
catch (Exception)
{
return MatchScores.Mismatch;
}
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public string[] GetPatterns()
{
return _patterns;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>Name</returns>
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "JsonPathMatcher";

View File

@@ -9,8 +9,8 @@ namespace WireMock.Matchers
/// <summary>
/// Regular Expression Matcher
/// </summary>
/// <seealso cref="IMatcher" />
public class RegexMatcher : IMatcher
/// <seealso cref="IStringMatcher" />
public class RegexMatcher : IStringMatcher
{
private readonly string[] _patterns;
private readonly Regex[] _expressions;
@@ -37,20 +37,20 @@ namespace WireMock.Matchers
RegexOptions options = RegexOptions.Compiled;
if (ignoreCase)
{
options |= RegexOptions.IgnoreCase;
}
_expressions = patterns.Select(p => new Regex(p, options)).ToArray();
}
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input string</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
if (input == null)
{
return MatchScores.Mismatch;
}
try
{
@@ -62,21 +62,13 @@ namespace WireMock.Matchers
}
}
/// <summary>
/// Gets the patterns.
/// </summary>
/// <returns>Pattern</returns>
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public virtual string[] GetPatterns()
{
return _patterns;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>
/// Name
/// </returns>
/// <inheritdoc cref="IMatcher.GetName"/>
public virtual string GetName()
{
return "RegexMatcher";

View File

@@ -9,21 +9,21 @@ namespace WireMock.Matchers.Request
/// </summary>
public class RequestMessageBodyMatcher : IRequestMatcher
{
/// <summary>
/// The body as byte[].
/// </summary>
private readonly byte[] _bodyData;
/// <summary>
/// The body function
/// </summary>
public Func<string, bool> Func { get; }
/// <summary>
/// The body data function
/// The body data function for byte[]
/// </summary>
public Func<byte[], bool> DataFunc { get; }
/// <summary>
/// The body data function for json
/// </summary>
public Func<object, bool> JsonFunc { get; }
/// <summary>
/// The matcher.
/// </summary>
@@ -32,9 +32,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="body">
/// The body Regex pattern.
/// </param>
/// <param name="body">The body.</param>
public RequestMessageBodyMatcher([NotNull] string body) : this(new SimMetricsMatcher(body))
{
}
@@ -42,21 +40,23 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="body">
/// The body Regex pattern.
/// </param>
public RequestMessageBodyMatcher([NotNull] byte[] body)
/// <param name="body">The body.</param>
public RequestMessageBodyMatcher([NotNull] byte[] body) : this(new ExactObjectMatcher(body))
{
Check.NotNull(body, nameof(body));
_bodyData = body;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="func">
/// The body func.
/// </param>
/// <param name="body">The body.</param>
public RequestMessageBodyMatcher([NotNull] object body) : this(new ExactObjectMatcher(body))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="func">The function.</param>
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
{
Check.NotNull(func, nameof(func));
@@ -66,9 +66,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="func">
/// The body func.
/// </param>
/// <param name="func">The function.</param>
public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)
{
Check.NotNull(func, nameof(func));
@@ -78,23 +76,24 @@ namespace WireMock.Matchers.Request
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="matcher">
/// The body matcher.
/// </param>
/// <param name="func">The function.</param>
public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)
{
Check.NotNull(func, nameof(func));
JsonFunc = func;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
/// </summary>
/// <param name="matcher">The matcher.</param>
public RequestMessageBodyMatcher([NotNull] IMatcher matcher)
{
Check.NotNull(matcher, nameof(matcher));
Matcher = matcher;
}
/// <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>
/// <see cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);
@@ -103,17 +102,43 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (Matcher != null)
return Matcher.IsMatch(requestMessage.Body);
if (requestMessage.Body != null)
{
var stringMatcher = Matcher as IStringMatcher;
if (stringMatcher != null)
{
return stringMatcher.IsMatch(requestMessage.Body);
}
}
if (_bodyData != null)
return MatchScores.ToScore(requestMessage.BodyAsBytes == _bodyData);
var objectMatcher = Matcher as IObjectMatcher;
if (objectMatcher != null)
{
if (requestMessage.BodyAsJson != null)
{
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
}
if (requestMessage.BodyAsBytes != null)
{
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
}
}
if (Func != null)
{
return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));
}
if (DataFunc != null && requestMessage.BodyAsBytes != null)
if (DataFunc != null)
{
return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));
}
if (JsonFunc != null)
{
return MatchScores.ToScore(requestMessage.BodyAsJson != null && JsonFunc(requestMessage.BodyAsJson));
}
return MatchScores.Mismatch;
}

View File

@@ -14,7 +14,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The matchers.
/// </summary>
public IReadOnlyList<IMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher> Matchers { get; }
/// <summary>
/// The ClientIP functions.
@@ -25,7 +25,7 @@ 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<IMatcher>().ToArray())
public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(ip)).Cast<IStringMatcher>().ToArray())
{
}
@@ -33,7 +33,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
/// </summary>
/// <param name="matchers">The matchers.</param>
public RequestMessageClientIPMatcher([NotNull] params IMatcher[] matchers)
public RequestMessageClientIPMatcher([NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(matchers, nameof(matchers));
Matchers = matchers;
@@ -59,10 +59,14 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (Matchers != null)
{
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));
}
if (Funcs != null)
{
return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.ClientIP)));
}
return MatchScores.Mismatch;
}

View File

@@ -24,7 +24,7 @@ namespace WireMock.Matchers.Request
/// <value>
/// The matchers.
/// </value>
public IMatcher[] Matchers { get; }
public IStringMatcher[] Matchers { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
@@ -38,7 +38,7 @@ namespace WireMock.Matchers.Request
Check.NotNull(pattern, nameof(pattern));
Name = name;
Matchers = new IMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
}
/// <summary>
@@ -46,7 +46,7 @@ namespace WireMock.Matchers.Request
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IMatcher[] matchers)
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNull(matchers, nameof(matchers));
@@ -83,16 +83,24 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (requestMessage.Cookies == null)
{
return MatchScores.Mismatch;
}
if (Funcs != null)
{
return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Cookies)));
}
if (Matchers == null)
{
return MatchScores.Mismatch;
}
if (!requestMessage.Cookies.ContainsKey(Name))
{
return MatchScores.Mismatch;
}
string value = requestMessage.Cookies[Name];
return Matchers.Max(m => m.IsMatch(value));

View File

@@ -26,7 +26,7 @@ namespace WireMock.Matchers.Request
/// <value>
/// The matchers.
/// </value>
public IMatcher[] Matchers { get; }
public IStringMatcher[] Matchers { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
@@ -40,7 +40,7 @@ namespace WireMock.Matchers.Request
Check.NotNull(pattern, nameof(pattern));
Name = name;
Matchers = new IMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
}
/// <summary>
@@ -55,7 +55,7 @@ namespace WireMock.Matchers.Request
Check.NotNull(patterns, nameof(patterns));
Name = name;
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IMatcher>().ToArray();
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IStringMatcher>().ToArray();
}
/// <summary>
@@ -63,7 +63,7 @@ namespace WireMock.Matchers.Request
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IMatcher[] matchers)
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNull(matchers, nameof(matchers));
@@ -93,16 +93,24 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (requestMessage.Headers == null)
{
return MatchScores.Mismatch;
}
if (Funcs != null)
{
return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Headers.ToDictionary(entry => entry.Key, entry => entry.Value.ToArray()))));
}
if (Matchers == null)
{
return MatchScores.Mismatch;
}
if (!requestMessage.Headers.ContainsKey(Name))
{
return MatchScores.Mismatch;
}
WireMockList<string> list = requestMessage.Headers[Name];
return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?

View File

@@ -14,7 +14,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The matcher.
/// </summary>
public IReadOnlyList<IMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher> Matchers { get; }
/// <summary>
/// The path functions
@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
/// </summary>
/// <param name="paths">The paths.</param>
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).Cast<IMatcher>().ToArray())
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).Cast<IStringMatcher>().ToArray())
{
}
@@ -33,7 +33,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
/// </summary>
/// <param name="matchers">The matchers.</param>
public RequestMessagePathMatcher([NotNull] params IMatcher[] matchers)
public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(matchers, nameof(matchers));
Matchers = matchers;
@@ -59,10 +59,14 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (Matchers != null)
{
return Matchers.Max(m => m.IsMatch(requestMessage.Path));
}
if (Funcs != null)
{
return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));
}
return MatchScores.Mismatch;
}

View File

@@ -14,7 +14,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The matchers.
/// </summary>
public IReadOnlyList<IMatcher> Matchers { get; }
public IReadOnlyList<IStringMatcher> Matchers { get; }
/// <summary>
/// The url functions.
@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
/// </summary>
/// <param name="urls">The urls.</param>
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).Cast<IMatcher>().ToArray())
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).Cast<IStringMatcher>().ToArray())
{
}
@@ -33,7 +33,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
/// </summary>
/// <param name="matchers">The matchers.</param>
public RequestMessageUrlMatcher([NotNull] params IMatcher[] matchers)
public RequestMessageUrlMatcher([NotNull] params IStringMatcher[] matchers)
{
Check.NotNull(matchers, nameof(matchers));
Matchers = matchers;
@@ -59,10 +59,14 @@ namespace WireMock.Matchers.Request
private double IsMatch(RequestMessage requestMessage)
{
if (Matchers != null)
{
return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));
}
if (Funcs != null)
{
return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));
}
return MatchScores.Mismatch;
}

View File

@@ -10,8 +10,8 @@ namespace WireMock.Matchers
/// <summary>
/// SimMetricsMatcher
/// </summary>
/// <seealso cref="IMatcher" />
public class SimMetricsMatcher : IMatcher
/// <seealso cref="IStringMatcher" />
public class SimMetricsMatcher : IStringMatcher
{
private readonly string[] _patterns;
private readonly SimMetricType _simMetricType;
@@ -38,11 +38,7 @@ namespace WireMock.Matchers
_simMetricType = simMetricType;
}
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input string</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
IStringMetric m = GetStringMetricType();
@@ -93,19 +89,13 @@ namespace WireMock.Matchers
}
}
/// <summary>
/// Gets the pattern.
/// </summary>
/// <returns>Pattern</returns>
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public string[] GetPatterns()
{
return _patterns;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>Name</returns>
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return $"SimMetricsMatcher.{_simMetricType}";

View File

@@ -7,7 +7,7 @@ namespace WireMock.Matchers
/// <summary>
/// WildcardMatcher
/// </summary>
/// <seealso cref="IMatcher" />
/// <seealso cref="RegexMatcher" />
public class WildcardMatcher : RegexMatcher
{
private readonly string[] _patterns;
@@ -31,21 +31,13 @@ namespace WireMock.Matchers
_patterns = patterns;
}
/// <summary>
/// Gets the pattern.
/// </summary>
/// <returns>Pattern</returns>
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public override string[] GetPatterns()
{
return _patterns;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>
/// Name
/// </returns>
/// <inheritdoc cref="IMatcher.GetName"/>
public override string GetName()
{
return "WildcardMatcher";

View File

@@ -12,8 +12,8 @@ namespace WireMock.Matchers
/// <summary>
/// XPath2Matcher
/// </summary>
/// <seealso cref="WireMock.Matchers.IMatcher" />
public class XPathMatcher : IMatcher
/// <seealso cref="IStringMatcher" />
public class XPathMatcher : IStringMatcher
{
private readonly string[] _patterns;
@@ -28,15 +28,13 @@ namespace WireMock.Matchers
_patterns = patterns;
}
/// <summary>
/// Determines whether the specified input is match.
/// </summary>
/// <param name="input">The input string</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
public double IsMatch(string input)
{
if (input == null)
{
return MatchScores.Mismatch;
}
try
{
@@ -53,19 +51,13 @@ namespace WireMock.Matchers
}
}
/// <summary>
/// Gets the patterns.
/// </summary>
/// <returns>Patterns</returns>
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
public string[] GetPatterns()
{
return _patterns;
}
/// <summary>
/// Gets the name.
/// </summary>
/// <returns>Name</returns>
/// <inheritdoc cref="IMatcher.GetName"/>
public string GetName()
{
return "XPathMatcher";

View File

@@ -2,7 +2,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -50,7 +49,7 @@ namespace WireMock.Owin
_host = new WebHostBuilder()
.Configure(appBuilder =>
{
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
appBuilder.UseMiddleware<GlobalExceptionMiddleware>(_options);
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
@@ -70,13 +69,13 @@ namespace WireMock.Owin
foreach (string url in _urls.Where(u => u.StartsWith("http://", StringComparison.OrdinalIgnoreCase)))
{
PortUtil.TryExtractProtocolAndPort(url, out string host, out int port);
options.Listen(IPAddress.Loopback, port);
options.Listen(System.Net.IPAddress.Loopback, port);
}
foreach (string url in _urls.Where(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{
PortUtil.TryExtractProtocolAndPort(url, out string host, out int port);
options.Listen(IPAddress.Loopback, port, listenOptions =>
options.Listen(System.Net.IPAddress.Loopback, port, listenOptions =>
{
listenOptions.UseHttps(PublicCertificateHelper.GetX509Certificate2());
});
@@ -88,20 +87,20 @@ namespace WireMock.Owin
#endif
.Build();
IsStarted = true;
#if NETSTANDARD1_3
Console.WriteLine("WireMock.Net server using netstandard1.3");
return Task.Run(() =>
{
_host.Run(_cts.Token);
IsStarted = true;
}, _cts.Token);
#else
System.Console.WriteLine("WireMock.Net server using netstandard2.0");
IsStarted = true;
return Task.Run(() =>
{
_host.Run();
IsStarted = true;
}, _cts.Token);
#endif
}

View File

@@ -1,6 +1,5 @@
using System;
using System.Threading.Tasks;
using log4net;
using Newtonsoft.Json;
#if !NETSTANDARD
using Microsoft.Owin;
@@ -16,13 +15,18 @@ namespace WireMock.Owin
internal class GlobalExceptionMiddleware
#endif
{
private static readonly ILog Log = LogManager.GetLogger(typeof(GlobalExceptionMiddleware));
private readonly WireMockMiddlewareOptions _options;
#if !NETSTANDARD
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next) { }
public GlobalExceptionMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)
{
_options = options;
}
#else
public GlobalExceptionMiddleware(RequestDelegate next)
public GlobalExceptionMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)
{
Next = next;
_options = options;
}
#endif
@@ -44,7 +48,7 @@ namespace WireMock.Owin
}
catch (Exception ex)
{
Log.Error("HttpStatusCode set to 500", ex);
_options.Logger.Error("HttpStatusCode set to 500 {0}", ex);
await _responseMapper.MapAsync(new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) }, ctx.Response);
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
// using System.IO;
using System.Linq;
using System.Text;
// using System.Text;
using System.Threading.Tasks;
using WireMock.Util;
#if !NETSTANDARD

View File

@@ -57,11 +57,15 @@ namespace WireMock.Owin
private void StartServers()
{
#if NET46
Console.WriteLine("WireMock.Net server using .net 4.6.x or higher");
#else
Console.WriteLine("WireMock.Net server using .net 4.5.x or higher");
#endif
Action<IAppBuilder> startup = app =>
{
app.Use<GlobalExceptionMiddleware>();
app.Use<GlobalExceptionMiddleware>(_options);
_options.PreWireMockMiddlewareInit?.Invoke(app);
app.Use<WireMockMiddleware>(_options);
_options.PostWireMockMiddlewareInit?.Invoke(app);

View File

@@ -3,7 +3,6 @@ using System.Threading.Tasks;
using WireMock.Logging;
using WireMock.Matchers.Request;
using System.Linq;
using log4net;
using WireMock.Matchers;
using WireMock.Util;
using Newtonsoft.Json;
@@ -22,7 +21,6 @@ namespace WireMock.Owin
internal class WireMockMiddleware
#endif
{
private static readonly ILog Log = LogManager.GetLogger(typeof(WireMockMiddleware));
private static readonly Task CompletedTask = Task.FromResult(false);
private readonly WireMockMiddlewareOptions _options;
@@ -98,7 +96,7 @@ namespace WireMock.Owin
if (targetMapping == null)
{
logRequest = true;
Log.Warn("HttpStatusCode set to 404 : No matching mapping found");
_options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");
response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };
return;
}
@@ -110,7 +108,7 @@ namespace WireMock.Owin
bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<string> authorization);
if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfect)
{
Log.Error("HttpStatusCode set to 401");
_options.Logger.Error("HttpStatusCode set to 401");
response = new ResponseMessage { StatusCode = 401 };
return;
}
@@ -130,7 +128,7 @@ namespace WireMock.Owin
}
catch (Exception ex)
{
Log.Error("HttpStatusCode set to 500", ex);
_options.Logger.Error("HttpStatusCode set to 500");
response = new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) };
}
finally

View File

@@ -15,13 +15,15 @@ namespace WireMock.Owin
{
internal class WireMockMiddlewareOptions
{
public IWireMockLogger Logger { get; set; }
public TimeSpan? RequestProcessingDelay { get; set; }
public IMatcher AuthorizationMatcher { get; set; }
public IStringMatcher AuthorizationMatcher { get; set; }
public bool AllowPartialMapping { get; set; }
public IDictionary<Guid, Mapping> Mappings { get; set; } = new ConcurrentDictionary<Guid, Mapping>();
public IDictionary<Guid, Mapping> Mappings { get; } = new ConcurrentDictionary<Guid, Mapping>();
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurentObservableCollection<LogEntry>();

View File

@@ -10,38 +10,52 @@ namespace WireMock.RequestBuilders
public interface IBodyRequestBuilder
{
/// <summary>
/// The with body.
/// WithBody: IMatcher
/// </summary>
/// <param name="matcher">The matcher.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] IMatcher matcher);
/// <summary>
/// The with body.
/// WithBody: Body as string
/// </summary>
/// <param name="body">The body.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(string body);
/// <summary>
/// The with body byte[].
/// WithBody: Body as byte[]
/// </summary>
/// <param name="body">The body as byte[].</param>
/// <param name="body">The body.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(byte[] body);
/// <summary>
/// The with body string func.
/// WithBody: Body as object
/// </summary>
/// <param name="body">The body string function.</param>
/// <param name="body">The body.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<string, bool> body);
IRequestBuilder WithBody(object body);
/// <summary>
/// The with body byte[] func.
///WithBody: func (string)
/// </summary>
/// <param name="body">The body byte[] function.</param>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<byte[], bool> body);
IRequestBuilder WithBody([NotNull] Func<string, bool> func);
/// <summary>
///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)
/// </summary>
/// <param name="func">The function.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] Func<object, bool> func);
}
}

View File

@@ -14,7 +14,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithClientIP([NotNull] params IMatcher[] matchers);
IRequestBuilder WithClientIP([NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with ClientIP.

View File

@@ -35,7 +35,7 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IMatcher[] matchers);
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with header.
@@ -59,7 +59,7 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IMatcher[] matchers);
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with cookie.

View File

@@ -14,7 +14,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params IMatcher[] matchers);
IRequestBuilder WithPath([NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with path.
@@ -35,7 +35,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params IMatcher[] matchers);
IRequestBuilder WithUrl([NotNull] params IStringMatcher[] matchers);
/// <summary>
/// The with url.

View File

@@ -59,7 +59,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithClientIP(params IMatcher[] matchers)
public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -98,7 +98,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithPath(params IMatcher[] matchers)
public IRequestBuilder WithPath(params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -137,7 +137,7 @@ namespace WireMock.RequestBuilders
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithUrl(params IMatcher[] matchers)
public IRequestBuilder WithUrl(params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -234,67 +234,28 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="body">
/// The body.
/// </param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string)"/>
public IRequestBuilder WithBody(string body)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
return this;
}
/// <summary>
/// The with body byte[].
/// </summary>
/// <param name="body">
/// The body as byte[].
/// </param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[])"/>
public IRequestBuilder WithBody(byte[] body)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="func">
/// The body function.
/// </param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithBody(Func<string, bool> func)
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object)"/>
public IRequestBuilder WithBody(object body)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="func">
/// The body function.
/// </param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithBody(Func<byte[], bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="matcher">The matcher.</param>
/// <returns>The <see cref="IRequestBuilder" />.</returns>
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher)"/>
public IRequestBuilder WithBody(IMatcher matcher)
{
Check.NotNull(matcher, nameof(matcher));
@@ -303,16 +264,34 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with parameters.
/// </summary>
/// <param name="key">
/// The key.
/// </param>
/// <param name="values">
/// The values.
/// </param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>
public IRequestBuilder WithBody(Func<string, bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{byte[], bool})"/>
public IRequestBuilder WithBody(Func<byte[], bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{object, bool})"/>
public IRequestBuilder WithBody(Func<object, bool> func)
{
Check.NotNull(func, nameof(func));
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
}
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, string[])"/>
public IRequestBuilder WithParam(string key, params string[] values)
{
Check.NotNull(key, nameof(key));
@@ -321,11 +300,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The with parameters.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IParamsRequestBuilder.WithParam(Func{IDictionary{string, WireMockList{string}}, bool}[])"/>
public IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
{
Check.NotNullOrEmpty(funcs, nameof(funcs));
@@ -360,7 +335,7 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithHeader(string name, params IMatcher[] matchers)
public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNullOrEmpty(matchers, nameof(matchers));
@@ -401,7 +376,7 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithCookie(string name, params IMatcher[] matchers)
public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)
{
Check.NotNullOrEmpty(matchers, nameof(matchers));

View File

@@ -18,6 +18,17 @@ namespace WireMock.ResponseBuilders
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBody([NotNull] string body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
/// <summary>
/// WithBody : Create a ... response based on a callback function.
/// </summary>
/// <param name="bodyFactory">The delegate to build the body.</param>
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
/// <param name="encoding">The body encoding.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBody([NotNull] Func<RequestMessage,string> bodyFactory, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
/// <summary>
/// WithBody : Create a ... response based on a bytearray.
/// </summary>

View File

@@ -0,0 +1,19 @@
using System;
using JetBrains.Annotations;
using WireMock.ResponseProviders;
namespace WireMock.ResponseBuilders
{
/// <summary>
/// The CallbackResponseBuilder interface.
/// </summary>
public interface ICallbackResponseBuilder : IResponseProvider
{
/// <summary>
/// The callback builder
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, ResponseMessage> callbackHandler);
}
}

View File

@@ -5,7 +5,7 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The DelayResponseBuilder interface.
/// </summary>
public interface IDelayResponseBuilder : IResponseProvider
public interface IDelayResponseBuilder : ICallbackResponseBuilder
{
/// <summary>
/// The with delay.

View File

@@ -7,7 +7,6 @@ using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Http;
using WireMock.Settings;
using WireMock.Transformers;
@@ -49,11 +48,13 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// Gets the response message.
/// </summary>
/// <value>
/// The response message.
/// </value>
public ResponseMessage ResponseMessage { get; }
/// <summary>
/// A delegate to execute to generate the response
/// </summary>
public Func<RequestMessage, ResponseMessage> Callback { get; private set; }
/// <summary>
/// Creates this instance.
/// </summary>
@@ -166,6 +167,13 @@ namespace WireMock.ResponseBuilders
return this;
}
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, string}, string, Encoding)"/>
public IResponseBuilder WithBody(Func<RequestMessage, string> bodyFactory, string destination = BodyDestinationFormat.SameAsSource,
Encoding encoding = null)
{
return WithCallback(req => new ResponseMessage {Body = bodyFactory(req)});
}
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(byte[], string, Encoding)"/>
public IResponseBuilder WithBody(byte[] body, string destination, Encoding encoding = null)
{
@@ -309,6 +317,16 @@ namespace WireMock.ResponseBuilders
return WithProxy(settings.Url, settings.ClientX509Certificate2ThumbprintOrSubjectName);
}
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
Callback = callbackHandler;
return this;
}
/// <summary>
/// The provide response.
/// </summary>
@@ -337,6 +355,11 @@ namespace WireMock.ResponseBuilders
return ResponseMessageTransformer.Transform(requestMessage, ResponseMessage);
}
if (Callback != null)
{
return Callback(requestMessage);
}
return ResponseMessage;
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Validation;
namespace WireMock.ResponseProviders
{
internal class DynamicAsyncResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, Task<ResponseMessage>> _responseMessageFunc;
public DynamicAsyncResponseProvider([NotNull] Func<RequestMessage, Task<ResponseMessage>> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
_responseMessageFunc = responseMessageFunc;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
{
return _responseMessageFunc(requestMessage);
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Validation;
namespace WireMock.ResponseProviders
{
internal class DynamicResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, ResponseMessage> _responseMessageFunc;
public DynamicResponseProvider([NotNull] Func<RequestMessage, ResponseMessage> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
_responseMessageFunc = responseMessageFunc;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
{
return Task.FromResult(_responseMessageFunc(requestMessage));
}
}
}

View File

@@ -1,7 +1,7 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace WireMock
namespace WireMock.ResponseProviders
{
/// <summary>
/// The Response Provider interface.

View File

@@ -0,0 +1,28 @@
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Settings;
using WireMock.Validation;
namespace WireMock.ResponseProviders
{
internal class ProxyAsyncResponseProvider : IResponseProvider
{
private readonly Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> _responseMessageFunc;
private readonly IProxyAndRecordSettings _settings;
public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> responseMessageFunc, [NotNull] IProxyAndRecordSettings settings)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
Check.NotNull(settings, nameof(settings));
_responseMessageFunc = responseMessageFunc;
_settings = settings;
}
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
{
return _responseMessageFunc(requestMessage, _settings);
}
}
}

View File

@@ -166,7 +166,8 @@ namespace WireMock.Serialization
return null;
}
var patterns = matcher.GetPatterns();
IStringMatcher stringMatcher = matcher as IStringMatcher;
string[] patterns = stringMatcher != null ? stringMatcher.GetPatterns() : new string[0];
return new MatcherModel
{
@@ -192,7 +193,9 @@ namespace WireMock.Serialization
public static IMatcher Map([CanBeNull] MatcherModel matcher)
{
if (matcher == null)
{
return null;
}
var parts = matcher.Name.Split('.');
string matcherName = parts[0];

View File

@@ -17,6 +17,7 @@ using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.ResponseProviders;
using WireMock.Serialization;
using WireMock.Settings;
using WireMock.Util;
@@ -113,7 +114,7 @@ namespace WireMock.Server
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
{
Log.InfoFormat("Reading Static MappingFile : '{0}'", filename);
_logger.Info("Reading Static MappingFile : '{0}'", filename);
ReadStaticMappingAndAddOrUpdate(filename);
}
}
@@ -135,22 +136,22 @@ namespace WireMock.Server
return;
}
Log.InfoFormat("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
_logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 1000);
watcher.Created += (sender, args) =>
{
Log.InfoFormat("New MappingFile created : '{0}'", args.FullPath);
_logger.Info("New MappingFile created : '{0}'", args.FullPath);
ReadStaticMappingAndAddOrUpdate(args.FullPath);
};
watcher.Changed += (sender, args) =>
{
Log.InfoFormat("New MappingFile updated : '{0}'", args.FullPath);
_logger.Info("New MappingFile updated : '{0}'", args.FullPath);
ReadStaticMappingAndAddOrUpdate(args.FullPath);
};
watcher.Deleted += (sender, args) =>
{
Log.InfoFormat("New MappingFile deleted : '{0}'", args.FullPath);
_logger.Info("New MappingFile deleted : '{0}'", args.FullPath);
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);
if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
@@ -288,7 +289,7 @@ namespace WireMock.Server
if (mapping == null)
{
Log.Warn("HttpStatusCode set to 404 : Mapping not found");
_logger.Warn("HttpStatusCode set to 404 : Mapping not found");
return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };
}
@@ -343,7 +344,7 @@ namespace WireMock.Server
string filename = !string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString();
string filePath = Path.Combine(folder, filename + ".json");
Log.InfoFormat("Saving Mapping to file {0}", filePath);
_logger.Info("Saving Mapping to file {0}", filePath);
File.WriteAllText(filePath, JsonConvert.SerializeObject(model, _settings));
}
@@ -374,12 +375,12 @@ namespace WireMock.Server
}
catch (ArgumentException a)
{
Log.Error("HttpStatusCode set to 400", a);
_logger.Error("HttpStatusCode set to 400 {0}", a);
return new ResponseMessage { StatusCode = 400, Body = a.Message };
}
catch (Exception e)
{
Log.Error("HttpStatusCode set to 500", e);
_logger.Error("HttpStatusCode set to 500 {0}", e);
return new ResponseMessage { StatusCode = 500, Body = e.ToString() };
}
@@ -449,8 +450,8 @@ namespace WireMock.Server
if (entry == null)
{
Log.Warn("HttpStatusCode set to 404 : Request not found");
return new ResponseMessage {StatusCode = 404, Body = "Request not found"};
_logger.Warn("HttpStatusCode set to 404 : Request not found");
return new ResponseMessage { StatusCode = 404, Body = "Request not found" };
}
var model = ToLogEntryModel(entry);
@@ -606,7 +607,7 @@ namespace WireMock.Server
var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);
if (clientIPModel?.Matchers != null)
{
requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MappingConverter.Map).ToArray());
requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
}
}
}
@@ -623,7 +624,7 @@ namespace WireMock.Server
var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
if (pathModel?.Matchers != null)
{
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).ToArray());
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
}
}
}
@@ -640,7 +641,7 @@ namespace WireMock.Server
var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
if (urlModel?.Matchers != null)
{
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).ToArray());
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
}
}
}
@@ -654,7 +655,7 @@ namespace WireMock.Server
{
foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
{
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MappingConverter.Map).ToArray());
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
}
}
@@ -662,7 +663,7 @@ namespace WireMock.Server
{
foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
{
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MappingConverter.Map).ToArray());
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MappingConverter.Map).Cast<IStringMatcher>().ToArray());
}
}

View File

@@ -1,20 +1,20 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using log4net;
using Newtonsoft.Json;
using WireMock.Http;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.Settings;
using WireMock.Validation;
using WireMock.Owin;
using WireMock.ResponseProviders;
namespace WireMock.Server
{
@@ -23,7 +23,7 @@ namespace WireMock.Server
/// </summary>
public partial class FluentMockServer : IDisposable
{
private static readonly ILog Log = LogManager.GetLogger(typeof(FluentMockServer));
private readonly IWireMockLogger _logger;
private const int ServerStartDelay = 100;
private readonly IOwinSelfHost _httpServer;
private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
@@ -158,7 +158,10 @@ namespace WireMock.Server
private FluentMockServer(IFluentMockServerSettings settings)
{
Log.DebugFormat("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
settings.Logger = settings.Logger ?? new WireMockConsoleLogger();
_logger = settings.Logger;
_logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
if (settings.Urls != null)
{
@@ -172,14 +175,13 @@ namespace WireMock.Server
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
_options.Logger = _logger;
#if NETSTANDARD
_httpServer = new AspNetCoreSelfHost(_options, Urls);
#else
_httpServer = new OwinSelfHost(_options, Urls);
#endif
IsStarted = _httpServer.IsStarted;
Ports = _httpServer.Ports;
_httpServer.StartAsync();
@@ -187,6 +189,8 @@ namespace WireMock.Server
// Fix for 'Bug: Server not listening after Start() returns (on macOS)'
Task.Delay(ServerStartDelay).Wait();
IsStarted = _httpServer.IsStarted;
if (settings.AllowPartialMapping == true)
{
AllowPartialMapping();
@@ -318,7 +322,7 @@ namespace WireMock.Server
[PublicAPI]
public void AllowPartialMapping(bool allow = true)
{
Log.InfoFormat("AllowPartialMapping is set to {0}", allow);
_logger.Info("AllowPartialMapping is set to {0}", allow);
_options.AllowPartialMapping = allow;
}

View File

@@ -1,4 +1,5 @@
using System;
using WireMock.ResponseProviders;
namespace WireMock.Server
{

View File

@@ -1,5 +1,6 @@
using System;
using WireMock.Matchers.Request;
using WireMock.ResponseProviders;
namespace WireMock.Server
{

View File

@@ -1,6 +1,7 @@
using System;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Logging;
namespace WireMock.Settings
{
@@ -71,5 +72,10 @@ namespace WireMock.Settings
[PublicAPI]
[JsonIgnore]
public Action<object> PostWireMockMiddlewareInit { get; set; }
/// <inheritdoc cref="IFluentMockServerSettings.Logger"/>
[PublicAPI]
[JsonIgnore]
public IWireMockLogger Logger { get; set; } = new WireMockNullLogger();
}
}

View File

@@ -1,4 +1,6 @@
using System;
using JetBrains.Annotations;
using WireMock.Logging;
namespace WireMock.Settings
{
@@ -10,77 +12,98 @@ namespace WireMock.Settings
/// <summary>
/// Gets or sets the port.
/// </summary>
[PublicAPI]
int? Port { get; set; }
/// <summary>
/// Gets or sets the use SSL.
/// </summary>
// ReSharper disable once InconsistentNaming
[PublicAPI]
bool? UseSSL { get; set; }
/// <summary>
/// Gets or sets wether to start admin interface.
/// </summary>
[PublicAPI]
bool? StartAdminInterface { get; set; }
/// <summary>
/// Gets or sets if the static mappings should be read at startup.
/// </summary>
[PublicAPI]
bool? ReadStaticMappings { get; set; }
/// <summary>
/// Watch the static mapping files + folder for changes when running.
/// </summary>
[PublicAPI]
bool? WatchStaticMappings { get; set; }
/// <summary>
/// Gets or sets if the proxy and record settings.
/// </summary>
[PublicAPI]
IProxyAndRecordSettings ProxyAndRecordSettings { get; set; }
/// <summary>
/// Gets or sets the urls.
/// </summary>
[PublicAPI]
string[] Urls { get; set; }
/// <summary>
/// StartTimeout
/// </summary>
[PublicAPI]
int StartTimeout { get; set; }
/// <summary>
/// Allow Partial Mapping (default set to false).
/// </summary>
[PublicAPI]
bool? AllowPartialMapping { get; set; }
/// <summary>
/// The username needed for __admin access.
/// </summary>
[PublicAPI]
string AdminUsername { get; set; }
/// <summary>
/// The password needed for __admin access.
/// </summary>
[PublicAPI]
string AdminPassword { get; set; }
/// <summary>
/// The RequestLog expiration in hours (optional).
/// </summary>
[PublicAPI]
int? RequestLogExpirationDuration { get; set; }
/// <summary>
/// The MaxRequestLog count (optional).
/// </summary>
[PublicAPI]
int? MaxRequestLogCount { get; set; }
/// <summary>
/// Action which is called (with the IAppBuilder or IApplicationBuilder) before the internal WireMockMiddleware is initialized. [Optional]
/// </summary>
[PublicAPI]
Action<object> PreWireMockMiddlewareInit { get; set; }
/// <summary>
/// Action which is called (with the IAppBuilder or IApplicationBuilder) after the internal WireMockMiddleware is initialized. [Optional]
/// </summary>
[PublicAPI]
Action<object> PostWireMockMiddlewareInit { get; set; }
/// <summary>
/// The IWireMockLogger which logs Debug, Info, Warning or Error
/// </summary>
[PublicAPI]
IWireMockLogger Logger { get; set; }
}
}

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using HandlebarsDotNet;
using Newtonsoft.Json;
using WireMock.Util;
namespace WireMock.Transformers
@@ -9,13 +10,31 @@ namespace WireMock.Transformers
{
public static ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original)
{
var responseMessage = new ResponseMessage { StatusCode = original.StatusCode, BodyOriginal = original.Body };
bool bodyIsJson = original.BodyAsJson != null;
var responseMessage = new ResponseMessage { StatusCode = original.StatusCode };
if (!bodyIsJson)
{
responseMessage.BodyOriginal = original.Body;
}
var template = new { request = requestMessage };
// Body
var templateBody = Handlebars.Compile(original.Body);
responseMessage.Body = templateBody(template);
string body = bodyIsJson ? JsonConvert.SerializeObject(original.BodyAsJson) : original.Body;
if (body != null)
{
var templateBody = Handlebars.Compile(body);
if (!bodyIsJson)
{
responseMessage.Body = templateBody(template);
}
else
{
responseMessage.BodyAsJson = JsonConvert.DeserializeObject(templateBody(template));
}
}
// Headers
var newHeaders = new Dictionary<string, WireMockList<string>>();

View File

@@ -10,7 +10,13 @@ namespace WireMock.Util
{
internal static class BodyParser
{
private static readonly string[] TextContentTypes = { "text/", "application/xml", "application/javascript", "application/typescript", "application/xhtml+xml" };
private static readonly string[] TextContentTypes =
{
"text/",
"application/javascript", "application/typescript",
"application/xml", "application/xhtml+xml",
"application/x-www-form-urlencoded"
};
private static async Task<Tuple<string, Encoding>> ReadStringAsync(Stream stream)
{

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.2</Version>
<Version>1.0.3.7</Version>
<Authors>Alexandre Victoor;Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@@ -45,7 +45,6 @@
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
<PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="RestEase" Version="1.4.4" />
<PackageReference Include="log4net" Version="2.0.8" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net452' ">
@@ -55,7 +54,11 @@
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.3" />
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.4" />
<PackageReference Include="Microsoft.Owin" Version="4.0.0" />
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.0.0" />
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.0.0" />
<PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="XPath2" Version="1.0.5.1" />
</ItemGroup>

View File

@@ -6,6 +6,7 @@ using NFluent;
using RestEase;
using WireMock.Admin.Mappings;
using WireMock.Client;
using WireMock.Logging;
using WireMock.Server;
using WireMock.Settings;
using Xunit;
@@ -25,7 +26,7 @@ namespace WireMock.Net.Tests
public async Task IFluentMockServerAdmin_FindRequestsAsync()
{
// given
_server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true });
_server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, Logger = new WireMockNullLogger() });
var serverUrl = "http://localhost:" + _server.Ports[0];
await new HttpClient().GetAsync(serverUrl + "/foo");
var api = RestClient.For<IFluentMockServerAdmin>(serverUrl);
@@ -45,7 +46,7 @@ namespace WireMock.Net.Tests
public async Task IFluentMockServerAdmin_GetRequestsAsync()
{
// given
_server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true });
_server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true, Logger = new WireMockNullLogger() });
var serverUrl = "http://localhost:" + _server.Ports[0];
await new HttpClient().GetAsync(serverUrl + "/foo");
var api = RestClient.For<IFluentMockServerAdmin>(serverUrl);

View File

@@ -89,13 +89,12 @@ namespace WireMock.Net.Tests
}
[Fact]
public void FluentMockServer_Admin_Mappings_Get()
public void FluentMockServer_Admin_Mappings_WithGuid_Get()
{
Guid guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
_server = FluentMockServer.Start();
_server.Given(Request.Create().WithPath("/foo1").UsingGet())
.WithGuid(guid)
_server.Given(Request.Create().WithPath("/foo1").UsingGet()).WithGuid(guid)
.RespondWith(Response.Create().WithStatusCode(201).WithBody("1"));
_server.Given(Request.Create().WithPath("/foo2").UsingGet())
@@ -105,6 +104,19 @@ namespace WireMock.Net.Tests
Check.That(mappings).HasSize(2);
}
[Fact]
public void FluentMockServer_Admin_Mappings_WithGuidAsString_Get()
{
string guid = "90356dba-b36c-469a-a17e-669cd84f1f05";
_server = FluentMockServer.Start();
_server.Given(Request.Create().WithPath("/foo1").UsingGet()).WithGuid(guid)
.RespondWith(Response.Create().WithStatusCode(201).WithBody("1"));
var mappings = _server.Mappings.ToArray();
Check.That(mappings).HasSize(1);
}
[Fact]
public void FluentMockServer_Admin_Mappings_Add_SameGuid()
{
@@ -220,6 +232,27 @@ namespace WireMock.Net.Tests
Check.That(response).IsEqualTo("Hello world!");
}
[Fact]
public async Task FluentMockServer_Should_respond_to_request_bodyAsCallback()
{
// given
_server = FluentMockServer.Start();
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody(req => $"{{ path: '{req.Path}' }}"));
// when
var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
// then
Check.That(response).IsEqualTo("{ path: '/foo' }");
}
[Fact]
public async Task FluentMockServer_Should_respond_to_request_bodyAsBase64()
{
@@ -432,6 +465,23 @@ namespace WireMock.Net.Tests
Check.That(requestLoggedB.RequestMessage.Path).EndsWith("/foo3");
}
[Fact]
public async Task FluentMockServer_Should_respond_to_request_callback()
{
// Assign
_server = FluentMockServer.Start();
_server
.Given(Request.Create().WithPath("/foo").UsingGet())
.RespondWith(Response.Create().WithCallback(req => new ResponseMessage { Body = req.Path + "Bar" }));
// Act
string response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
// Assert
Check.That(response).IsEqualTo("/fooBar");
}
public void Dispose()
{
_server?.Stop();

View File

@@ -0,0 +1,23 @@
using NFluent;
using WireMock.Matchers;
using Xunit;
namespace WireMock.Net.Tests.Matchers
{
public class ExactObjectMatcherTests
{
[Fact]
public void ExactObjectMatcher_GetName()
{
// Assign
object obj = 1;
// Act
var matcher = new ExactObjectMatcher(obj);
string name = matcher.GetName();
// Assert
Check.That(name).Equals("ExactObjectMatcher");
}
}
}

View File

@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests
@@ -13,6 +15,60 @@ namespace WireMock.Net.Tests
{
private const string ClientIp = "::1";
[Fact]
public void Request_WithBody_FuncString()
{
// Assign
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(b => b.Contains("b"));
// Act
var body = new BodyData
{
BodyAsString = "b"
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncJson()
{
// Assign
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(b => b != null);
// Act
var body = new BodyData
{
BodyAsJson = 123
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncByteArray()
{
// Assign
var requestBuilder = Request.Create().UsingAnyVerb().WithBody((byte[] b) => b != null);
// Act
var body = new BodyData
{
BodyAsBytes = new byte[0]
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyExactMatcher()
{
@@ -198,5 +254,108 @@ namespace WireMock.Net.Tests
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Object_JsonPathMatcher_true()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"));
// when
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, bodyData);
// then
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)]"));
// when
string jsonString = "{ \"books\": [ { \"category\": \"test1\", \"price\": 8.95 }, { \"category\": \"test2\", \"price\": 20 } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, bodyData);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Array_JsonPathMatcher_2()
{
// given
var spec = Request.Create().UsingAnyVerb().WithBody(new JsonPathMatcher("$..[?(@.Id == 1)]"));
// when
string jsonString = "{ \"Id\": 1, \"Name\": \"Test\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, bodyData);
// then
var requestMatchResult = new RequestMatchResult();
double result = spec.GetMatchingScore(request, requestMatchResult);
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsObject_ExactObjectMatcher_true()
{
// Assign
object body = DateTime.MinValue;
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(body);
var bodyData = new BodyData
{
BodyAsJson = DateTime.MinValue
};
// Act
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsBytes_ExactObjectMatcher_true()
{
// Assign
byte[] body = { 123 };
var requestBuilder = Request.Create().UsingAnyVerb().WithBody(body);
var bodyData = new BodyData
{
BodyAsBytes = new byte[] { 123 }
};
// Act
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using Xunit;
@@ -35,5 +36,33 @@ namespace WireMock.Net.Tests
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(0.0);
}
[Fact]
public void Request_WithClientIP_WildcardMatcher()
{
// given
var spec = Request.Create().WithClientIP(new WildcardMatcher("127.0.0.2"));
// when
var request = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithClientIP_Func()
{
// given
var spec = Request.Create().WithClientIP(c => c.Contains("."));
// when
var request = new RequestMessage(new Uri("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using Xunit;
@@ -25,10 +26,24 @@ namespace WireMock.Net.Tests
}
[Fact]
public void Request_WithUrlExact()
public void Request_WithUrl_WildcardMatcher()
{
// given
var spec = Request.Create().WithUrl("http://localhost/foo");
var spec = Request.Create().WithUrl(new WildcardMatcher("*/foo"));
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithUrl_Func()
{
// given
var spec = Request.Create().WithUrl(url => url.Contains("foo"));
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "blabla", ClientIp);

View File

@@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NFluent;
using WireMock.ResponseBuilders;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests
@@ -12,6 +14,29 @@ namespace WireMock.Net.Tests
{
private const string ClientIp = "::1";
[Fact]
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson()
{
// given
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
Encoding = Encoding.UTF8
};
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp, bodyData);
var response = Response.Create()
.WithBodyAsJson(new { x = "test {{request.url}}" })
.WithTransformer();
// act
var responseMessage = await response.ProvideResponseAsync(request);
// then
Check.That(JsonConvert.SerializeObject(responseMessage.BodyAsJson)).Equals("{\"x\":\"test http://localhost/foo\"}");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
{

View File

@@ -1,5 +1,4 @@
using System;
using System.Net;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using NFluent;
@@ -10,101 +9,86 @@ using Xunit;
namespace WireMock.Net.Tests
{
public class StatefulBehaviorTests : IDisposable
public class StatefulBehaviorTests
{
private FluentMockServer _server;
[Fact]
public async Task Should_skip_non_relevant_states()
{
// given
_server = FluentMockServer.Start();
var server = FluentMockServer.Start();
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
server
.Given(Request.Create().WithPath("/foo").UsingGet())
.InScenario("s")
.WhenStateIs("Test state")
.RespondWith(Response.Create());
// when
var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
var response = await new HttpClient().GetAsync("http://localhost:" + server.Ports[0] + "/foo");
// then
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
server.Dispose();
}
[Fact]
public async Task Should_process_request_if_equals_state_and_single_state_defined()
{
// given
_server = FluentMockServer.Start();
var server = FluentMockServer.Start();
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
server
.Given(Request.Create().WithPath("/foo").UsingGet())
.InScenario("s")
.WillSetStateTo("Test state")
.RespondWith(Response.Create()
.WithBody("No state msg"));
.RespondWith(Response.Create().WithBody("No state msg"));
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
server
.Given(Request.Create().WithPath("/foo").UsingGet())
.InScenario("s")
.WhenStateIs("Test state")
.RespondWith(Response.Create()
.WithBody("Test state msg"));
.RespondWith(Response.Create().WithBody("Test state msg"));
// when
var responseNoState = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
var responseWithState = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
var responseNoState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo");
var responseWithState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo");
// then
Check.That(responseNoState).Equals("No state msg");
Check.That(responseWithState).Equals("Test state msg");
server.Dispose();
}
[Fact]
public async Task Scenario_and_State_TodoList_Example()
{
// Assign
_server = FluentMockServer.Start();
var server = FluentMockServer.Start();
_server
.Given(Request.Create()
.WithPath("/todo/items")
.UsingGet())
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario("To do list")
.WillSetStateTo("TodoList State Started")
.RespondWith(Response.Create()
.WithBody("Buy milk"));
.RespondWith(Response.Create().WithBody("Buy milk"));
_server
.Given(Request.Create()
.WithPath("/todo/items")
.UsingPost())
server
.Given(Request.Create().WithPath("/todo/items").UsingPost())
.InScenario("To do list")
.WhenStateIs("TodoList State Started")
.WillSetStateTo("Cancel newspaper item added")
.RespondWith(Response.Create()
.WithStatusCode(201));
.RespondWith(Response.Create().WithStatusCode(201));
_server
.Given(Request.Create()
.WithPath("/todo/items")
.UsingGet())
server
.Given(Request.Create().WithPath("/todo/items").UsingGet())
.InScenario("To do list")
.WhenStateIs("Cancel newspaper item added")
.RespondWith(Response.Create()
.WithBody("Buy milk;Cancel newspaper subscription"));
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
// Act and Assert
string url = "http://localhost:" + _server.Ports[0];
string getResponse1 = await new HttpClient().GetStringAsync(url + "/todo/items");
string url = "http://localhost:" + server.Ports[0];
string getResponse1 = new HttpClient().GetStringAsync(url + "/todo/items").Result;
Check.That(getResponse1).Equals("Buy milk");
var postResponse = await new HttpClient().PostAsync(url + "/todo/items", new StringContent("Cancel newspaper subscription"));
@@ -112,68 +96,55 @@ namespace WireMock.Net.Tests
string getResponse2 = await new HttpClient().GetStringAsync(url + "/todo/items");
Check.That(getResponse2).Equals("Buy milk;Cancel newspaper subscription");
server.Dispose();
}
[Fact]
// [Fact]
public async Task Should_process_request_if_equals_state_and_multiple_state_defined()
{
// given
_server = FluentMockServer.Start();
// Assign
var server = FluentMockServer.Start();
_server
.Given(Request.Create()
.WithPath("/state1")
.UsingGet())
server
.Given(Request.Create().WithPath("/state1").UsingGet())
.InScenario("s1")
.WillSetStateTo("Test state 1")
.RespondWith(Response.Create()
.WithBody("No state msg 1"));
.RespondWith(Response.Create().WithBody("No state msg 1"));
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
server
.Given(Request.Create().WithPath("/fooX").UsingGet())
.InScenario("s1")
.WhenStateIs("Test state 1")
.RespondWith(Response.Create()
.WithBody("Test state msg 1"));
.RespondWith(Response.Create().WithBody("Test state msg 1"));
_server
.Given(Request.Create()
.WithPath("/state2")
.UsingGet())
server
.Given(Request.Create().WithPath("/state2").UsingGet())
.InScenario("s2")
.WillSetStateTo("Test state 2")
.RespondWith(Response.Create()
.WithBody("No state msg 2"));
.RespondWith(Response.Create().WithBody("No state msg 2"));
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
server
.Given(Request.Create().WithPath("/fooX").UsingGet())
.InScenario("s2")
.WhenStateIs("Test state 2")
.RespondWith(Response.Create()
.WithBody("Test state msg 2"));
.RespondWith(Response.Create().WithBody("Test state msg 2"));
// when
string url = "http://localhost:" + _server.Ports[0];
// Act and Assert
string url = "http://localhost:" + server.Ports[0];
var responseNoState1 = await new HttpClient().GetStringAsync(url + "/state1");
var responseNoState2 = await new HttpClient().GetStringAsync(url + "/state2");
var responseWithState1 = await new HttpClient().GetStringAsync(url + "/foo");
var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo");
// then
Check.That(responseNoState1).Equals("No state msg 1");
Check.That(responseWithState1).Equals("Test state msg 1");
Check.That(responseNoState2).Equals("No state msg 2");
Check.That(responseWithState2).Equals("Test state msg 2");
}
public void Dispose()
{
_server?.Dispose();
var responseNoState2 = await new HttpClient().GetStringAsync(url + "/state2");
Check.That(responseNoState2).Equals("No state msg 2");
var responseWithState1 = await new HttpClient().GetStringAsync(url + "/fooX");
Check.That(responseWithState1).Equals("Test state msg 1");
var responseWithState2 = await new HttpClient().GetStringAsync(url + "/fooX");
Check.That(responseWithState2).Equals("Test state msg 2");
server.Dispose();
}
}
}

View File

@@ -16,9 +16,9 @@
<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.1" />
<PackageReference Include="Moq" Version="4.8.2" />
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="NFluent" Version="2.0.0" />
<PackageReference Include="NFluent" Version="2.2.0" />
<PackageReference Include="OpenCover" Version="4.6.519" />
<PackageReference Include="ReportGenerator" Version="2.5.11" />
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />