mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-23 01:04:55 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1a184ebfdf | ||
|
|
4b91c05fe7 | ||
|
|
c92e733ef9 | ||
|
|
d9fde9329a | ||
|
|
9e7d3b6d2d | ||
|
|
5ee25fb1e7 | ||
|
|
36866d9fc3 | ||
|
|
4f7259d27a | ||
|
|
f13b829c00 | ||
|
|
60d9487313 | ||
|
|
8cb15b2311 |
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,3 +1,22 @@
|
||||
# 1.0.4.10 (14 August 2018)
|
||||
|
||||
- [#180](https://github.com/WireMock-Net/WireMock.Net/pull/180) - Add IFileSystemHandler to support Azure for StaticMapping location contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||
- [#173](https://github.com/WireMock-Net/WireMock.Net/issues/173) - Feature: Mapping files lost when restarting an Azure app service +feature
|
||||
|
||||
Commits: 4b91c05fe7...4b91c05fe7
|
||||
|
||||
|
||||
# 1.0.4.9 (08 August 2018)
|
||||
|
||||
- [#177](https://github.com/WireMock-Net/WireMock.Net/issues/177) - Feature: Skip invalid static mapping files +feature
|
||||
- [#176](https://github.com/WireMock-Net/WireMock.Net/issues/176) - Question: Saving mapping with relative (not found) file fails
|
||||
- [#175](https://github.com/WireMock-Net/WireMock.Net/issues/175) - Bug: Don't allow adding a mapping with no URL or PATH +fix
|
||||
- [#174](https://github.com/WireMock-Net/WireMock.Net/issues/174) - Bug: JsonMatcher and JsonPathMatcher throws when posting byte[] +fix
|
||||
- [#172](https://github.com/WireMock-Net/WireMock.Net/issues/172) - Question: Same/similar fluent interface for in process and admin client API
|
||||
|
||||
Commits: 8cb15b2311...d9fde9329a
|
||||
|
||||
|
||||
# 1.0.4.8 (23 July 2018)
|
||||
|
||||
- [#170](https://github.com/WireMock-Net/WireMock.Net/pull/170) - Support json path in the response contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
https://github.com/GitTools/GitReleaseNotes
|
||||
|
||||
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.4.8
|
||||
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.4.10
|
||||
|
||||
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags
|
||||
|
||||
57
README.md
57
README.md
@@ -1,7 +1,16 @@
|
||||
# WireMock.Net
|
||||
A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) which mimics the functionality from the JAVA based [WireMock.org](http://WireMock.org).
|
||||
|
||||
### Info
|
||||
## Key Features
|
||||
* HTTP response stubbing, matchable on URL/Path, headers, cookies and body content patterns
|
||||
* Runs in unit tests, as a standalone process, as windows service, as Azure or IIS or as docker
|
||||
* Configurable via a fluent DotNet API, JSON files and JSON over HTTP
|
||||
* Record/playback of stubs
|
||||
* Per-request conditional proxying
|
||||
* Stateful behaviour simulation
|
||||
* Configurable response delays
|
||||
|
||||
## Info
|
||||
| | |
|
||||
| --- | --- |
|
||||
| ***Project*** | |
|
||||
@@ -26,44 +35,38 @@ The following frameworks are supported:
|
||||
- net 4.5.2 and up & net 4.6 and up
|
||||
- netstandard 1.3 & netstandard 2.0
|
||||
|
||||
## Build info
|
||||
### Build info
|
||||
To build you need:
|
||||
- Microsoft .NET Framework 4.5.2 Developer Pack (https://www.microsoft.com/en-us/download/details.aspx?id=42637)
|
||||
- Microsoft .NET Framework 4.6 Targeting Pack (https://www.microsoft.com/en-us/download/confirmation.aspx?id=48136)
|
||||
- Microsoft .NET Framework 4.6.2 Developer Pack (https://www.microsoft.com/en-us/download/confirmation.aspx?id=53321)
|
||||
- .NET Core 2.0 (https://www.microsoft.com/net/core)
|
||||
|
||||
|
||||
## Stubbing
|
||||
A core feature of WireMock.Net is the ability to return canned/predefined HTTP responses for requests matching criteria, see [Wiki : Stubbing & Request Matching](https://github.com/WireMock-Net/WireMock.Net/wiki/Stubbing-and-Request-Matching).
|
||||
|
||||
## Using WireMock.Net in UnitTest framework
|
||||
You can use your favorite test framework and use WireMock within your tests, see
|
||||
[Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests).
|
||||
|
||||
## Admin API Reference
|
||||
The WireMock admin API provides functionality to define the mappings via a http interface, see [Wiki : Admin API Reference](https://github.com/StefH/WireMock.Net/wiki/Admin-API-Reference).
|
||||
|
||||
## WireMock.Net as a standalone process
|
||||
This is quite straight forward to launch a mock server within a console application, see [Wiki : standalone](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process).
|
||||
## Using
|
||||
WireMock.Net can be used in several ways:
|
||||
|
||||
## WireMock.Net in a docker container
|
||||
### UnitTesting
|
||||
You can use your favorite test framework and use WireMock within your tests, see
|
||||
[Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests).
|
||||
|
||||
### As standalone process / console application
|
||||
This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process).
|
||||
|
||||
### As a Windows Service
|
||||
You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service).
|
||||
|
||||
### As a Web Job in Azure or application in IIS
|
||||
See this link [WireMock-as-a-(Azure)-Web-App](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-(Azure)-Web-App)
|
||||
|
||||
### In a docker container
|
||||
There is also a Linux and Windows-Nano container available at [hub.docker.com](https://hub.docker.com/r/sheyenrath).
|
||||
For more details see also [WireMock.Net-docker](https://github.com/WireMock-Net/WireMock.Net-docker).
|
||||
For more details see also [Docker](https://github.com/WireMock-Net/WireMock.Net-docker).
|
||||
|
||||
### SSL
|
||||
You can start a standalone mock server listening for HTTPS requests. To do so, there is just a flag to set when creating the server:
|
||||
```csharp
|
||||
var server1 = FluentMockServer.Start(port: 8443, ssl: true);
|
||||
|
||||
// or like this
|
||||
|
||||
var server2 = FluentMockServer.Start(new FluentMockServerSettings
|
||||
{
|
||||
Urls = new[] { "http://localhost:9091", "https://localhost:9443" }
|
||||
});
|
||||
```
|
||||
|
||||
- In case when using **net 4.5.2** or **net 4.6**, you need a certificate registered on your box, properly associated with your application and the port number that will be used. This is not really specific to WireMock.Net, not very straightforward and hence the following stackoverflow thread might come handy: [Httplistener with https support](http://stackoverflow.com/questions/11403333/httplistener-with-https-support).
|
||||
|
||||
- When using **netstandard**, WireMock.Net uses a self signed certificate (which can be overriden if you like) to host https urls.
|
||||
#### HTTPS / SSL
|
||||
More details on using HTTPS (SSL) can be found here [Wiki : HTTPS](https://github.com/WireMock-Net/WireMock.Net/wiki/Using-HTTPS-(SSL))
|
||||
|
||||
@@ -54,6 +54,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Service", "exa
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.HeadersTest", "examples\WireMock.Net.Console.HeadersTest\WireMock.Net.Console.HeadersTest.csproj", "{B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp2", "examples\WireMock.Net.Console.NETCoreApp2\WireMock.Net.Console.NETCoreApp2.csproj", "{83645809-9E01-4E81-8733-BA9497554ABF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -120,6 +122,10 @@ Global
|
||||
{B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -140,6 +146,7 @@ Global
|
||||
{3C279524-DB73-4DE3-BEF1-F2B2958C9F65} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{B70278E7-A2C6-4A3B-BBA9-1C873CA6F03C} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{83645809-9E01-4E81-8733-BA9497554ABF} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
|
||||
|
||||
@@ -7,15 +7,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="__admin\mappings\826aff7c-6208-4a3c-923d-575248907db4.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net.ConsoleApplication\CustomFileSystemFileHandler.cs" Link="CustomFileSystemFileHandler.cs" />
|
||||
<Compile Include="..\WireMock.Net.ConsoleApplication\MainApp.cs" Link="MainApp.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
||||
<Content Include="__admin\mappings\*.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
@@ -3,14 +3,7 @@
|
||||
"Title": "",
|
||||
"Priority": 0,
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/proxy-google-test-post"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Path": "/proxy-google-test-post",
|
||||
"Methods": [
|
||||
"post"
|
||||
],
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
|
||||
"Priority": 4,
|
||||
"Request": {
|
||||
"Path": {},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"BodyDestination": "SameAsSource",
|
||||
"Body": "NO PATH OR URL",
|
||||
"UseTransformer": false,
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<StartupObject>WireMock.Net.Console.NETCoreApp.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net.ConsoleApplication\CustomFileSystemFileHandler.cs" Link="CustomFileSystemFileHandler.cs" />
|
||||
<Compile Include="..\WireMock.Net.ConsoleApplication\MainApp.cs" Link="MainApp.cs" />
|
||||
<Compile Include="..\WireMock.Net.Console.NETCoreApp\Program.cs" Link="Program.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="__admin\mappings\*.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\WireMock.Net.Console.NETCoreApp\log4net.config" Link="log4net.config" />
|
||||
<None Include="..\WireMock.Net.Console.NETCoreApp\nlog.config" Link="nlog.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
<PackageReference Include="log4net" Version="2.0.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="log4net.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="nlog.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\791a3f31-6946-4ce7-8e6f-0237c7443275.json">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/static/mapping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"BodyAsJson": { "body": "static mapping" },
|
||||
"Headers": {
|
||||
"Content-Type": "application/json",
|
||||
"Test-X": [ "test 1", "test 2" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"Guid": "791a3f31-6946-4ce7-8e6f-0237c7443275",
|
||||
"Title": "",
|
||||
"Priority": 0,
|
||||
"Request": {
|
||||
"Path": "/proxy-google-test-post",
|
||||
"Methods": [
|
||||
"post"
|
||||
],
|
||||
"Body": {}
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 404,
|
||||
"Body": "<!DOCTYPE html>\n<html lang=en>\n <meta charset=utf-8>\n <meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n <title>Error 404 (Not Found)!!1</title>\n <style>\n *{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}\n </style>\n <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\n <p><b>404.</b> <ins>That’s an error.</ins>\n <p>The requested URL <code>/proxy-google-test-post</code> was not found on this server. <ins>That’s all we know.</ins>\n",
|
||||
"BodyAsBytes": "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ZW4+CiAgPG1ldGEgY2hhcnNldD11dGYtOD4KICA8bWV0YSBuYW1lPXZpZXdwb3J0IGNvbnRlbnQ9ImluaXRpYWwtc2NhbGU9MSwgbWluaW11bS1zY2FsZT0xLCB3aWR0aD1kZXZpY2Utd2lkdGgiPgogIDx0aXRsZT5FcnJvciA0MDQgKE5vdCBGb3VuZCkhITE8L3RpdGxlPgogIDxzdHlsZT4KICAgICp7bWFyZ2luOjA7cGFkZGluZzowfWh0bWwsY29kZXtmb250OjE1cHgvMjJweCBhcmlhbCxzYW5zLXNlcmlmfWh0bWx7YmFja2dyb3VuZDojZmZmO2NvbG9yOiMyMjI7cGFkZGluZzoxNXB4fWJvZHl7bWFyZ2luOjclIGF1dG8gMDttYXgtd2lkdGg6MzkwcHg7bWluLWhlaWdodDoxODBweDtwYWRkaW5nOjMwcHggMCAxNXB4fSogPiBib2R5e2JhY2tncm91bmQ6dXJsKC8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2Vycm9ycy9yb2JvdC5wbmcpIDEwMCUgNXB4IG5vLXJlcGVhdDtwYWRkaW5nLXJpZ2h0OjIwNXB4fXB7bWFyZ2luOjExcHggMCAyMnB4O292ZXJmbG93OmhpZGRlbn1pbnN7Y29sb3I6Izc3Nzt0ZXh0LWRlY29yYXRpb246bm9uZX1hIGltZ3tib3JkZXI6MH1AbWVkaWEgc2NyZWVuIGFuZCAobWF4LXdpZHRoOjc3MnB4KXtib2R5e2JhY2tncm91bmQ6bm9uZTttYXJnaW4tdG9wOjA7bWF4LXdpZHRoOm5vbmU7cGFkZGluZy1yaWdodDowfX0jbG9nb3tiYWNrZ3JvdW5kOnVybCgvL3d3dy5nb29nbGUuY29tL2ltYWdlcy9icmFuZGluZy9nb29nbGVsb2dvLzF4L2dvb2dsZWxvZ29fY29sb3JfMTUweDU0ZHAucG5nKSBuby1yZXBlYXQ7bWFyZ2luLWxlZnQ6LTVweH1AbWVkaWEgb25seSBzY3JlZW4gYW5kIChtaW4tcmVzb2x1dGlvbjoxOTJkcGkpeyNsb2dve2JhY2tncm91bmQ6dXJsKC8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2JyYW5kaW5nL2dvb2dsZWxvZ28vMngvZ29vZ2xlbG9nb19jb2xvcl8xNTB4NTRkcC5wbmcpIG5vLXJlcGVhdCAwJSAwJS8xMDAlIDEwMCU7LW1vei1ib3JkZXItaW1hZ2U6dXJsKC8vd3d3Lmdvb2dsZS5jb20vaW1hZ2VzL2JyYW5kaW5nL2dvb2dsZWxvZ28vMngvZ29vZ2xlbG9nb19jb2xvcl8xNTB4NTRkcC5wbmcpIDB9fUBtZWRpYSBvbmx5IHNjcmVlbiBhbmQgKC13ZWJraXQtbWluLWRldmljZS1waXhlbC1yYXRpbzoyKXsjbG9nb3tiYWNrZ3JvdW5kOnVybCgvL3d3dy5nb29nbGUuY29tL2ltYWdlcy9icmFuZGluZy9nb29nbGVsb2dvLzJ4L2dvb2dsZWxvZ29fY29sb3JfMTUweDU0ZHAucG5nKSBuby1yZXBlYXQ7LXdlYmtpdC1iYWNrZ3JvdW5kLXNpemU6MTAwJSAxMDAlfX0jbG9nb3tkaXNwbGF5OmlubGluZS1ibG9jaztoZWlnaHQ6NTRweDt3aWR0aDoxNTBweH0KICA8L3N0eWxlPgogIDxhIGhyZWY9Ly93d3cuZ29vZ2xlLmNvbS8+PHNwYW4gaWQ9bG9nbyBhcmlhLWxhYmVsPUdvb2dsZT48L3NwYW4+PC9hPgogIDxwPjxiPjQwNC48L2I+IDxpbnM+VGhhdOKAmXMgYW4gZXJyb3IuPC9pbnM+CiAgPHA+VGhlIHJlcXVlc3RlZCBVUkwgPGNvZGU+L3Byb3h5LWdvb2dsZS10ZXN0LXBvc3Q8L2NvZGU+IHdhcyBub3QgZm91bmQgb24gdGhpcyBzZXJ2ZXIuICA8aW5zPlRoYXTigJlzIGFsbCB3ZSBrbm93LjwvaW5zPgo=",
|
||||
"BodyEncoding": {
|
||||
"CodePage": 65001,
|
||||
"EncodingName": "Unicode (UTF-8)",
|
||||
"WebName": "utf-8"
|
||||
},
|
||||
"UseTransformer": false,
|
||||
"Headers": {
|
||||
"Date": "Wed, 27 Oct 2017 18:57:40 GMT",
|
||||
"Alt-Svc": "quic=\":443\"; ma=2592000; v=\"39,38,37,35\"",
|
||||
"Referrer-Policy": "no-referrer",
|
||||
"Connection": "close"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
|
||||
"Priority": 4,
|
||||
"Request": {
|
||||
"Path": {},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"BodyDestination": "SameAsSource",
|
||||
"Body": "NO PATH OR URL",
|
||||
"UseTransformer": false,
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using WireMock.Handlers;
|
||||
|
||||
namespace WireMock.Net.ConsoleApplication
|
||||
{
|
||||
internal class CustomFileSystemFileHandler : IFileSystemHandler
|
||||
{
|
||||
private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.FolderExists"/>
|
||||
public bool FolderExists(string path)
|
||||
{
|
||||
return Directory.Exists(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.CreateFolder"/>
|
||||
public void CreateFolder(string path)
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.EnumerateFiles"/>
|
||||
public IEnumerable<string> EnumerateFiles(string path)
|
||||
{
|
||||
return Directory.EnumerateFiles(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.GetMappingFolder"/>
|
||||
public string GetMappingFolder()
|
||||
{
|
||||
return Path.Combine(@"c:\temp-wiremock", AdminMappingsFolder);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.ReadMappingFile"/>
|
||||
public string ReadMappingFile(string path)
|
||||
{
|
||||
return File.ReadAllText(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.WriteMappingFile"/>
|
||||
public void WriteMappingFile(string path, string text)
|
||||
{
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,9 @@ namespace WireMock.Net.ConsoleApplication
|
||||
//},
|
||||
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
|
||||
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); },
|
||||
Logger = new WireMockConsoleLogger()
|
||||
Logger = new WireMockConsoleLogger(),
|
||||
|
||||
FileSystemHandler = new CustomFileSystemFileHandler()
|
||||
});
|
||||
System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(",", server.Urls));
|
||||
|
||||
@@ -38,6 +40,14 @@ namespace WireMock.Net.ConsoleApplication
|
||||
|
||||
server.AllowPartialMapping();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
|
||||
.AtPriority(4)
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody(@"{ ""result"": ""Contains x with FUNC 200""}"));
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingGet()
|
||||
@@ -53,7 +63,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithPath("/proxy-execute-keep-alive")
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithProxy(new ProxyAndRecordSettings { Url = "http://localhost:9999", BlackListedHeaders = new [] { "Keep-Alive" } })
|
||||
.WithProxy(new ProxyAndRecordSettings { Url = "http://localhost:9999", BlackListedHeaders = new[] { "Keep-Alive" } })
|
||||
.WithHeader("Keep-Alive-Test", "stef")
|
||||
);
|
||||
|
||||
@@ -144,8 +154,10 @@ namespace WireMock.Net.ConsoleApplication
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/file_rel").UsingGet())
|
||||
.WithGuid("0000aaaa-fcf4-4256-a0d3-1c76e4862947")
|
||||
.RespondWith(Response.Create()
|
||||
.WithBodyFromFile("Program.cs", false)
|
||||
.WithHeader("Content-Type", "application/xml")
|
||||
.WithBodyFromFile("WireMock.Net.xml", false)
|
||||
);
|
||||
|
||||
server
|
||||
@@ -176,14 +188,6 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithStatusCode(200)
|
||||
.WithBody("hi"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(p => p.Contains("x")).UsingGet())
|
||||
.AtPriority(4)
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody(@"{ ""result"": ""Contains x with FUNC 200""}"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/data").UsingPost().WithBody(b => b.Contains("e")))
|
||||
.AtPriority(999)
|
||||
@@ -284,7 +288,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.Given(Request.Create().WithPath("/jsonpathtestTokenJson").UsingPost())
|
||||
.RespondWith(Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { status = "OK", url = "{{request.url}}", transformed = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" } )
|
||||
.WithBodyAsJson(new { status = "OK", url = "{{request.url}}", transformed = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" })
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
<Reference Include="System.XML" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CustomFileSystemFileHandler.cs" />
|
||||
<Compile Include="MainApp.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@@ -71,6 +72,9 @@
|
||||
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="__admin\mappings\873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj">
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
|
||||
"Priority": 4,
|
||||
"Request": {
|
||||
"Path": {},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"BodyDestination": "SameAsSource",
|
||||
"Body": "NO PATH OR URL",
|
||||
"UseTransformer": false,
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||
<Version>1.0.4.8</Version>
|
||||
<Version>1.0.4.10</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
49
src/WireMock.Net/Handlers/IFileSystemHandler.cs
Normal file
49
src/WireMock.Net/Handlers/IFileSystemHandler.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Handlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to handle folders and read and write static mapping files.
|
||||
/// </summary>
|
||||
public interface IFileSystemHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the folder where the static mappings are located. For local file system, this would be `{CurrentFolder}/__admin/mappings`.
|
||||
/// </summary>
|
||||
/// <returns>The foldername.</returns>
|
||||
string GetMappingFolder();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given path refers to an existing directory on disk.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>true if path refers to an existing directory; false if the directory does not exist or an error occurs when trying to determine if the specified directory exists.</returns>
|
||||
bool FolderExists(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Creates all directories and subdirectories in the specified path unless they already exist.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
void CreateFolder(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerable collection of file names in a specified path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
/// <returns>An enumerable collection of the full names (including paths) for the files in the directory specified by path.</returns>
|
||||
IEnumerable<string> EnumerateFiles(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Read a static mapping file as text.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
string ReadMappingFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Write the static mapping.
|
||||
/// </summary>
|
||||
/// <param name="path">The path (folder + filename with .json extension).</param>
|
||||
/// <param name="text">The text.</param>
|
||||
void WriteMappingFile(string path, string text);
|
||||
}
|
||||
}
|
||||
49
src/WireMock.Net/Handlers/LocalFileSystemHandler.cs
Normal file
49
src/WireMock.Net/Handlers/LocalFileSystemHandler.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace WireMock.Handlers
|
||||
{
|
||||
/// <summary>
|
||||
/// Default implementation for a handler to interact with the local file system to read and write static mapping files.
|
||||
/// </summary>
|
||||
public class LocalFileSystemHandler : IFileSystemHandler
|
||||
{
|
||||
private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.FolderExists"/>
|
||||
public bool FolderExists(string path)
|
||||
{
|
||||
return Directory.Exists(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.CreateFolder"/>
|
||||
public void CreateFolder(string path)
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.EnumerateFiles"/>
|
||||
public IEnumerable<string> EnumerateFiles(string path)
|
||||
{
|
||||
return Directory.EnumerateFiles(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.GetMappingFolder"/>
|
||||
public string GetMappingFolder()
|
||||
{
|
||||
return Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.ReadMappingFile"/>
|
||||
public string ReadMappingFile(string path)
|
||||
{
|
||||
return File.ReadAllText(path);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IFileSystemHandler.WriteMappingFile"/>
|
||||
public void WriteMappingFile(string path, string text)
|
||||
{
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,9 @@ namespace WireMock.Matchers
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
if (input != null)
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -65,7 +65,9 @@ namespace WireMock.Matchers
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
bool match = false;
|
||||
if (input != null)
|
||||
|
||||
// When input is null or byte[], return Mismatch.
|
||||
if (input != null && !(input is byte[]))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace WireMock.Serialization
|
||||
string matcherName = parts[0];
|
||||
string matcherType = parts.Length > 1 ? parts[1] : null;
|
||||
|
||||
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new [] { matcher.Pattern as string };
|
||||
string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.Cast<string>().ToArray() : new[] { matcher.Pattern as string };
|
||||
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
||||
|
||||
switch (matcherName)
|
||||
@@ -39,7 +39,7 @@ namespace WireMock.Serialization
|
||||
return new JsonPathMatcher(matchBehaviour, stringPatterns);
|
||||
|
||||
case "XPathMatcher":
|
||||
return new XPathMatcher(matchBehaviour, (string) matcher.Pattern);
|
||||
return new XPathMatcher(matchBehaviour, (string)matcher.Pattern);
|
||||
|
||||
case "WildcardMatcher":
|
||||
return new WildcardMatcher(matchBehaviour, stringPatterns, matcher.IgnoreCase == true);
|
||||
@@ -51,7 +51,7 @@ namespace WireMock.Serialization
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||
}
|
||||
|
||||
return new SimMetricsMatcher(matchBehaviour, (string) matcher.Pattern, type);
|
||||
return new SimMetricsMatcher(matchBehaviour, (string)matcher.Pattern, type);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
||||
|
||||
@@ -30,12 +30,13 @@ namespace WireMock.Server
|
||||
/// </summary>
|
||||
public partial class FluentMockServer
|
||||
{
|
||||
private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");
|
||||
private const string ContentTypeJson = "application/json";
|
||||
|
||||
private const string AdminMappings = "/__admin/mappings";
|
||||
private const string AdminRequests = "/__admin/requests";
|
||||
private const string AdminSettings = "/__admin/settings";
|
||||
private const string AdminScenarios = "/__admin/scenarios";
|
||||
|
||||
private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/mappings\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
|
||||
private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^\/__admin\/requests\/(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
|
||||
|
||||
@@ -100,44 +101,66 @@ namespace WireMock.Server
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region StaticMappings
|
||||
#region StaticMappings
|
||||
/// <summary>
|
||||
/// Saves the static mappings.
|
||||
/// </summary>
|
||||
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
|
||||
[PublicAPI]
|
||||
public void SaveStaticMappings([CanBeNull] string folder = null)
|
||||
{
|
||||
foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
|
||||
{
|
||||
SaveMappingToFile(mapping, folder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the static mappings from a folder.
|
||||
/// </summary>
|
||||
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
||||
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
|
||||
[PublicAPI]
|
||||
public void ReadStaticMappings([CanBeNull] string folder = null)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||
folder = _fileSystemHandler.GetMappingFolder();
|
||||
}
|
||||
|
||||
if (!Directory.Exists(folder))
|
||||
if (!_fileSystemHandler.FolderExists(folder))
|
||||
{
|
||||
_logger.Info("The Static Mapping folder '{0}' does not exist, reading Static MappingFiles will be skipped.", folder);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
|
||||
foreach (string filename in _fileSystemHandler.EnumerateFiles(folder).OrderBy(f => f))
|
||||
{
|
||||
_logger.Info("Reading Static MappingFile : '{0}'", filename);
|
||||
ReadStaticMappingAndAddOrUpdate(filename);
|
||||
|
||||
try
|
||||
{
|
||||
ReadStaticMappingAndAddOrUpdate(filename);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_logger.Error("Static MappingFile : '{0}' could not be read. This file will be skipped.", filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Watches the static mappings for changes.
|
||||
/// </summary>
|
||||
/// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
|
||||
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
|
||||
[PublicAPI]
|
||||
public void WatchStaticMappings([CanBeNull] string folder = null)
|
||||
{
|
||||
if (folder == null)
|
||||
{
|
||||
folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||
folder = _fileSystemHandler.GetMappingFolder();
|
||||
}
|
||||
|
||||
if (!Directory.Exists(folder))
|
||||
if (!_fileSystemHandler.FolderExists(folder))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -184,7 +207,7 @@ namespace WireMock.Server
|
||||
|
||||
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(FileHelper.ReadAllText(path));
|
||||
MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(_fileSystemHandler.ReadMappingFile(path));
|
||||
if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
|
||||
{
|
||||
DeserializeAndAddOrUpdateMapping(mappingModel, guidFromFilename, path);
|
||||
@@ -316,9 +339,9 @@ namespace WireMock.Server
|
||||
Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
|
||||
|
||||
var mappingModel = DeserializeObject<MappingModel>(requestMessage);
|
||||
DeserializeAndAddOrUpdateMapping(mappingModel, guid);
|
||||
Guid? guidFromPut = DeserializeAndAddOrUpdateMapping(mappingModel, guid);
|
||||
|
||||
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guid);
|
||||
return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);
|
||||
}
|
||||
|
||||
private ResponseMessage MappingDelete(RequestMessage requestMessage)
|
||||
@@ -337,29 +360,31 @@ namespace WireMock.Server
|
||||
#region Mappings
|
||||
private ResponseMessage MappingsSave(RequestMessage requestMessage)
|
||||
{
|
||||
foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
|
||||
{
|
||||
SaveMappingToFile(mapping);
|
||||
}
|
||||
SaveStaticMappings();
|
||||
|
||||
return ResponseMessageBuilder.Create("Mappings saved to disk");
|
||||
}
|
||||
|
||||
private void SaveMappingToFile(Mapping mapping)
|
||||
private void SaveMappingToFile(Mapping mapping, string folder = null)
|
||||
{
|
||||
string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
|
||||
if (!Directory.Exists(folder))
|
||||
if (folder == null)
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
folder = _fileSystemHandler.GetMappingFolder();
|
||||
}
|
||||
|
||||
if (!_fileSystemHandler.FolderExists(folder))
|
||||
{
|
||||
_fileSystemHandler.CreateFolder(folder);
|
||||
}
|
||||
|
||||
var model = MappingConverter.ToMappingModel(mapping);
|
||||
string filename = !string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString();
|
||||
string filename = (!string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToString()) + ".json";
|
||||
|
||||
string filePath = Path.Combine(folder, filename + ".json");
|
||||
_logger.Info("Saving Mapping to file {0}", filePath);
|
||||
string path = Path.Combine(folder, filename);
|
||||
|
||||
File.WriteAllText(filePath, JsonConvert.SerializeObject(model, _settings));
|
||||
_logger.Info("Saving Mapping file {0}", filename);
|
||||
|
||||
_fileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, _settings));
|
||||
}
|
||||
|
||||
private static string SanitizeFileName(string name, char replaceChar = '_')
|
||||
@@ -401,13 +426,18 @@ namespace WireMock.Server
|
||||
return ResponseMessageBuilder.Create("Mapping added", 201, guid);
|
||||
}
|
||||
|
||||
private Guid DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
|
||||
private Guid? DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
|
||||
{
|
||||
Check.NotNull(mappingModel, nameof(mappingModel));
|
||||
Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
|
||||
Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
|
||||
|
||||
var requestBuilder = InitRequestBuilder(mappingModel.Request);
|
||||
var requestBuilder = InitRequestBuilder(mappingModel.Request, true);
|
||||
if (requestBuilder == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var responseBuilder = InitResponseBuilder(mappingModel.Response);
|
||||
|
||||
var respondProvider = Given(requestBuilder);
|
||||
@@ -511,7 +541,7 @@ namespace WireMock.Server
|
||||
{
|
||||
var requestModel = DeserializeObject<RequestModel>(requestMessage);
|
||||
|
||||
var request = (Request)InitRequestBuilder(requestModel);
|
||||
var request = (Request)InitRequestBuilder(requestModel, false);
|
||||
|
||||
var dict = new Dictionary<LogEntry, RequestMatchResult>();
|
||||
foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))
|
||||
@@ -551,7 +581,7 @@ namespace WireMock.Server
|
||||
}
|
||||
#endregion
|
||||
|
||||
private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
|
||||
private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
|
||||
{
|
||||
IRequestBuilder requestBuilder = Request.Create();
|
||||
|
||||
@@ -571,11 +601,13 @@ namespace WireMock.Server
|
||||
}
|
||||
}
|
||||
|
||||
bool pathOrUrlmatchersValid = false;
|
||||
if (requestModel.Path != null)
|
||||
{
|
||||
if (requestModel.Path is string path)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithPath(path);
|
||||
pathOrUrlmatchersValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -583,15 +615,16 @@ namespace WireMock.Server
|
||||
if (pathModel?.Matchers != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
|
||||
pathOrUrlmatchersValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (requestModel.Url != null)
|
||||
else if (requestModel.Url != null)
|
||||
{
|
||||
if (requestModel.Url is string url)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithUrl(url);
|
||||
pathOrUrlmatchersValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -599,10 +632,17 @@ namespace WireMock.Server
|
||||
if (urlModel?.Matchers != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast<IStringMatcher>().ToArray());
|
||||
pathOrUrlmatchersValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pathOrUrlRequired && !pathOrUrlmatchersValid)
|
||||
{
|
||||
_logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (requestModel.Methods != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Http;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
@@ -14,7 +15,6 @@ using WireMock.Owin;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Transformers;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Server
|
||||
@@ -25,6 +25,8 @@ namespace WireMock.Server
|
||||
public partial class FluentMockServer : IDisposable
|
||||
{
|
||||
private readonly IWireMockLogger _logger;
|
||||
private readonly IFileSystemHandler _fileSystemHandler;
|
||||
|
||||
private const int ServerStartDelay = 100;
|
||||
private readonly IOwinSelfHost _httpServer;
|
||||
private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
|
||||
@@ -183,7 +185,9 @@ namespace WireMock.Server
|
||||
private FluentMockServer(IFluentMockServerSettings settings)
|
||||
{
|
||||
settings.Logger = settings.Logger ?? new WireMockConsoleLogger();
|
||||
|
||||
_logger = settings.Logger;
|
||||
_fileSystemHandler = settings.FileSystemHandler ?? new LocalFileSystemHandler();
|
||||
|
||||
_logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
|
||||
_logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
|
||||
namespace WireMock.Settings
|
||||
@@ -77,5 +78,10 @@ namespace WireMock.Settings
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public IWireMockLogger Logger { get; set; } = new WireMockNullLogger();
|
||||
|
||||
/// <inheritdoc cref="IFluentMockServerSettings.FileSystemHandler"/>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public IFileSystemHandler FileSystemHandler { get; set; } = new LocalFileSystemHandler();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
|
||||
namespace WireMock.Settings
|
||||
@@ -105,5 +106,11 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
IWireMockLogger Logger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to read and write static mapping files.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
@@ -8,17 +11,19 @@ namespace WireMock.Util
|
||||
private const int NumberOfRetries = 3;
|
||||
private const int DelayOnRetry = 500;
|
||||
|
||||
public static string ReadAllText(string path)
|
||||
public static string ReadAllTextWithRetryAndDelay([NotNull] IFileSystemHandler filehandler, [NotNull] string path)
|
||||
{
|
||||
Check.NotNull(filehandler, nameof(filehandler));
|
||||
Check.NotNullOrEmpty(path, nameof(path));
|
||||
|
||||
for (int i = 1; i <= NumberOfRetries; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.ReadAllText(path);
|
||||
return filehandler.ReadMappingFile(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// You may check error code to filter some exceptions, not every error can be recovered.
|
||||
Thread.Sleep(DelayOnRetry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.4.8</Version>
|
||||
<Version>1.0.4.10</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
@@ -14,6 +15,10 @@ using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using Xunit;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Admin.Mappings;
|
||||
|
||||
namespace WireMock.Net.Tests
|
||||
{
|
||||
@@ -42,6 +47,35 @@ namespace WireMock.Net.Tests
|
||||
server2.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FluentMockServer_SaveStaticMappings()
|
||||
{
|
||||
// Assign
|
||||
string guid = "791a3f31-6946-aaaa-8e6f-0237c7441111";
|
||||
var _staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
||||
_staticMappingHandlerMock.Setup(m => m.GetMappingFolder()).Returns("folder");
|
||||
_staticMappingHandlerMock.Setup(m => m.FolderExists(It.IsAny<string>())).Returns(true);
|
||||
_staticMappingHandlerMock.Setup(m => m.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()));
|
||||
|
||||
_server = FluentMockServer.Start(new FluentMockServerSettings
|
||||
{
|
||||
FileSystemHandler = _staticMappingHandlerMock.Object
|
||||
});
|
||||
|
||||
_server
|
||||
.Given(Request.Create().WithPath($"/foo_{Guid.NewGuid()}"))
|
||||
.WithGuid(guid)
|
||||
.RespondWith(Response.Create().WithBody("save test"));
|
||||
|
||||
// Act
|
||||
_server.SaveStaticMappings();
|
||||
|
||||
// Assert and Verify
|
||||
_staticMappingHandlerMock.Verify(m => m.GetMappingFolder(), Times.Once);
|
||||
_staticMappingHandlerMock.Verify(m => m.FolderExists("folder"), Times.Once);
|
||||
_staticMappingHandlerMock.Verify(m => m.WriteMappingFile(Path.Combine("folder", guid + ".json"), It.IsAny<string>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FluentMockServer_ReadStaticMapping_WithNonGuidFilename()
|
||||
{
|
||||
@@ -108,6 +142,49 @@ namespace WireMock.Net.Tests
|
||||
Check.That(mappings.First().Title).IsNullOrEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FluentMockServer_ReadStaticMappings_FolderExistsIsTrue()
|
||||
{
|
||||
// Assign
|
||||
var _staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
||||
_staticMappingHandlerMock.Setup(m => m.GetMappingFolder()).Returns("folder");
|
||||
_staticMappingHandlerMock.Setup(m => m.FolderExists(It.IsAny<string>())).Returns(true);
|
||||
_staticMappingHandlerMock.Setup(m => m.EnumerateFiles(It.IsAny<string>())).Returns(new string[0]);
|
||||
|
||||
_server = FluentMockServer.Start(new FluentMockServerSettings
|
||||
{
|
||||
FileSystemHandler = _staticMappingHandlerMock.Object
|
||||
});
|
||||
|
||||
// Act
|
||||
_server.ReadStaticMappings();
|
||||
|
||||
// Assert and Verify
|
||||
_staticMappingHandlerMock.Verify(m => m.GetMappingFolder(), Times.Once);
|
||||
_staticMappingHandlerMock.Verify(m => m.FolderExists("folder"), Times.Once);
|
||||
_staticMappingHandlerMock.Verify(m => m.EnumerateFiles("folder"), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FluentMockServer_ReadStaticMappingAndAddOrUpdate()
|
||||
{
|
||||
// Assign
|
||||
string mapping = "{\"Request\": {\"Path\": {\"Matchers\": [{\"Name\": \"WildcardMatcher\",\"Pattern\": \"/static/mapping\"}]},\"Methods\": [\"get\"]},\"Response\": {\"BodyAsJson\": { \"body\": \"static mapping\" }}}";
|
||||
var _staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
||||
_staticMappingHandlerMock.Setup(m => m.ReadMappingFile(It.IsAny<string>())).Returns(mapping);
|
||||
|
||||
_server = FluentMockServer.Start(new FluentMockServerSettings
|
||||
{
|
||||
FileSystemHandler = _staticMappingHandlerMock.Object
|
||||
});
|
||||
|
||||
// Act
|
||||
_server.ReadStaticMappingAndAddOrUpdate(@"c:\test.json");
|
||||
|
||||
// Assert and Verify
|
||||
_staticMappingHandlerMock.Verify(m => m.ReadMappingFile(@"c:\test.json"), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FluentMockServer_ReadStaticMappings()
|
||||
{
|
||||
@@ -142,7 +219,7 @@ namespace WireMock.Net.Tests
|
||||
string guid = "90356dba-b36c-469a-a17e-669cd84f1f05";
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
_server.Given(Request.Create().WithPath("/foo1").UsingGet()).WithGuid(guid)
|
||||
_server.Given(Request.Create().WithPath("/foo100").UsingGet()).WithGuid(guid)
|
||||
.RespondWith(Response.Create().WithStatusCode(201).WithBody("1"));
|
||||
|
||||
var mappings = _server.Mappings.ToArray();
|
||||
@@ -219,13 +296,14 @@ namespace WireMock.Net.Tests
|
||||
public async Task FluentMockServer_Should_respond_to_request_methodPatch()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
_server.Given(Request.Create().WithPath("/foo").UsingMethod("patch"))
|
||||
_server.Given(Request.Create().WithPath(path).UsingMethod("patch"))
|
||||
.RespondWith(Response.Create().WithBody("hello patch"));
|
||||
|
||||
// when
|
||||
var msg = new HttpRequestMessage(new HttpMethod("patch"), new Uri("http://localhost:" + _server.Ports[0] + "/foo"))
|
||||
var msg = new HttpRequestMessage(new HttpMethod("patch"), new Uri("http://localhost:" + _server.Ports[0] + path))
|
||||
{
|
||||
Content = new StringContent("{\"data\": {\"attr\":\"value\"}}")
|
||||
};
|
||||
@@ -338,13 +416,14 @@ namespace WireMock.Net.Tests
|
||||
public async Task FluentMockServer_Should_respond_to_request_bodyAsBytes()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
_server.Given(Request.Create().WithPath("/foo").UsingGet()).RespondWith(Response.Create().WithBody(new byte[] { 48, 49 }));
|
||||
_server.Given(Request.Create().WithPath(path).UsingGet()).RespondWith(Response.Create().WithBody(new byte[] { 48, 49 }));
|
||||
|
||||
// when
|
||||
var responseAsString = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
var responseAsBytes = await new HttpClient().GetByteArrayAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
var responseAsString = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + path);
|
||||
var responseAsBytes = await new HttpClient().GetByteArrayAsync("http://localhost:" + _server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
Check.That(responseAsString).IsEqualTo("01");
|
||||
@@ -371,13 +450,14 @@ namespace WireMock.Net.Tests
|
||||
|
||||
foreach (var item in validMatchersForHelloServerJsonMessage)
|
||||
{
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
_server
|
||||
.Given(Request.Create().WithPath("/foo").WithBody((IMatcher)item[0]))
|
||||
.Given(Request.Create().WithPath(path).WithBody((IMatcher)item[0]))
|
||||
.RespondWith(Response.Create().WithBody("Hello client"));
|
||||
|
||||
// Act
|
||||
var content = new StringContent(jsonRequestMessage, Encoding.UTF8, (string)item[1]);
|
||||
var response = await new HttpClient().PostAsync("http://localhost:" + _server.Ports[0] + "/foo", content);
|
||||
var response = await new HttpClient().PostAsync("http://localhost:" + _server.Ports[0] + path, content);
|
||||
|
||||
// Assert
|
||||
var responseString = await response.Content.ReadAsStringAsync();
|
||||
@@ -392,10 +472,11 @@ namespace WireMock.Net.Tests
|
||||
public async Task FluentMockServer_Should_respond_404_for_unexpected_request()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo{Guid.NewGuid()}";
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
// when
|
||||
var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
|
||||
@@ -405,20 +486,21 @@ namespace WireMock.Net.Tests
|
||||
[Fact]
|
||||
public async Task FluentMockServer_Should_find_a_request_satisfying_a_request_spec()
|
||||
{
|
||||
// given
|
||||
// Assign
|
||||
string path = $"/bar_{Guid.NewGuid()}";
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
// when
|
||||
await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/bar");
|
||||
await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
var result = _server.FindLogEntries(Request.Create().WithPath(new RegexMatcher("^/b.*"))).ToList();
|
||||
Check.That(result).HasSize(1);
|
||||
|
||||
var requestLogged = result.First();
|
||||
Check.That(requestLogged.RequestMessage.Path).IsEqualTo("/bar");
|
||||
Check.That(requestLogged.RequestMessage.Url).IsEqualTo("http://localhost:" + _server.Ports[0] + "/bar");
|
||||
Check.That(requestLogged.RequestMessage.Path).IsEqualTo(path);
|
||||
Check.That(requestLogged.RequestMessage.Url).IsEqualTo("http://localhost:" + _server.Ports[0] + path);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -439,11 +521,12 @@ namespace WireMock.Net.Tests
|
||||
public void FluentMockServer_Should_reset_mappings()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
_server
|
||||
.Given(Request.Create()
|
||||
.WithPath("/foo")
|
||||
.WithPath(path)
|
||||
.UsingGet())
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(@"{ msg: ""Hello world!""}"));
|
||||
@@ -453,35 +536,38 @@ namespace WireMock.Net.Tests
|
||||
|
||||
// then
|
||||
Check.That(_server.Mappings).IsEmpty();
|
||||
Check.ThatAsyncCode(() => new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo"))
|
||||
Check.ThatAsyncCode(() => new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + path))
|
||||
.ThrowsAny();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FluentMockServer_Should_respond_a_redirect_without_body()
|
||||
{
|
||||
// given
|
||||
// Assign
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
string pathToRedirect = $"/bar_{Guid.NewGuid()}";
|
||||
|
||||
_server = FluentMockServer.Start();
|
||||
|
||||
_server
|
||||
.Given(Request.Create()
|
||||
.WithPath("/foo")
|
||||
.WithPath(path)
|
||||
.UsingGet())
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(307)
|
||||
.WithHeader("Location", "/bar"));
|
||||
.WithHeader("Location", pathToRedirect));
|
||||
_server
|
||||
.Given(Request.Create()
|
||||
.WithPath("/bar")
|
||||
.WithPath(pathToRedirect)
|
||||
.UsingGet())
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
.WithBody("REDIRECT SUCCESSFUL"));
|
||||
|
||||
// when
|
||||
var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
// Act
|
||||
var response = await new HttpClient().GetStringAsync($"http://localhost:{_server.Ports[0]}{path}");
|
||||
|
||||
// then
|
||||
// Assert
|
||||
Check.That(response).IsEqualTo("REDIRECT SUCCESSFUL");
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,20 @@ namespace WireMock.Net.Tests.Matchers
|
||||
Check.That(value).Equals("{}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_ByteArray()
|
||||
{
|
||||
// Assign
|
||||
var bytes = new byte[0];
|
||||
var matcher = new JsonMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonMatcher_IsMatch_NullString()
|
||||
{
|
||||
|
||||
@@ -33,6 +33,20 @@ namespace WireMock.Net.Tests.Matchers
|
||||
Check.That(patterns).ContainsExactly("X");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_ByteArray()
|
||||
{
|
||||
// Assign
|
||||
var bytes = new byte[0];
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(bytes);
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_NullString()
|
||||
{
|
||||
|
||||
@@ -183,7 +183,7 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_ResponseBodyAsJson()
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Object_ResponseBodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
@@ -236,6 +236,27 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
Check.That(j["x"]["Name"].ToString()).Equals("Acme Co");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Number_ResponseBodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{ \"Price\": 99 }" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"..Price\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"].Value<long>()).Equals(99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Request_BodyAsString()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
@@ -16,16 +17,17 @@ namespace WireMock.Net.Tests
|
||||
public async Task Scenarios_Should_skip_non_relevant_states()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = FluentMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo").UsingGet())
|
||||
.Given(Request.Create().WithPath(path).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] + path);
|
||||
|
||||
// then
|
||||
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
|
||||
@@ -37,23 +39,24 @@ namespace WireMock.Net.Tests
|
||||
public async Task Scenarios_Should_process_request_if_equals_state_and_single_state_defined()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = FluentMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo").UsingGet())
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WillSetStateTo("Test state")
|
||||
.RespondWith(Response.Create().WithBody("No state msg"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo").UsingGet())
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WhenStateIs("Test state")
|
||||
.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] + path);
|
||||
var responseWithState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path);
|
||||
|
||||
// then
|
||||
Check.That(responseNoState).Equals("No state msg");
|
||||
|
||||
44
test/WireMock.Net.Tests/Util/FileHelperTests.cs
Normal file
44
test/WireMock.Net.Tests/Util/FileHelperTests.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Moq;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Util
|
||||
{
|
||||
public class FileHelperTests
|
||||
{
|
||||
[Fact]
|
||||
public void FileHelper_ReadAllTextWithRetryAndDelay()
|
||||
{
|
||||
// Assign
|
||||
var _staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
||||
_staticMappingHandlerMock.Setup(m => m.ReadMappingFile(It.IsAny<string>())).Returns("text");
|
||||
|
||||
// Act
|
||||
string result = FileHelper.ReadAllTextWithRetryAndDelay(_staticMappingHandlerMock.Object, @"c:\temp");
|
||||
|
||||
// Assert
|
||||
Check.That(result).Equals("text");
|
||||
|
||||
// Verify
|
||||
_staticMappingHandlerMock.Verify(m => m.ReadMappingFile(@"c:\temp"), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FileHelper_ReadAllTextWithRetryAndDelay_Throws()
|
||||
{
|
||||
// Assign
|
||||
var _staticMappingHandlerMock = new Mock<IFileSystemHandler>();
|
||||
_staticMappingHandlerMock.Setup(m => m.ReadMappingFile(It.IsAny<string>())).Throws<NotSupportedException>();
|
||||
|
||||
// Act
|
||||
Check.ThatCode(() => FileHelper.ReadAllTextWithRetryAndDelay(_staticMappingHandlerMock.Object, @"c:\temp")).Throws<IOException>();
|
||||
|
||||
// Verify
|
||||
_staticMappingHandlerMock.Verify(m => m.ReadMappingFile(@"c:\temp"), Times.Exactly(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user