mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
Compare commits
38 Commits
WireMockSe
...
1.2.11.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c42c2d5d7a | ||
|
|
d67a160144 | ||
|
|
7033d85e3a | ||
|
|
7d873611ee | ||
|
|
f26bf62a13 | ||
|
|
6938b6f73c | ||
|
|
5b2cd061a6 | ||
|
|
80993c7740 | ||
|
|
d4d0f8becd | ||
|
|
cd613d1c76 | ||
|
|
5f4c688e49 | ||
|
|
e7949a47d9 | ||
|
|
a6cf7a48dc | ||
|
|
bf5afef7a1 | ||
|
|
a8934ec7f9 | ||
|
|
d2ac56e49a | ||
|
|
e8a4d52797 | ||
|
|
dac73b6fe0 | ||
|
|
e91be0a4d1 | ||
|
|
a9974a4874 | ||
|
|
1ddd8ff58f | ||
|
|
5174f9823c | ||
|
|
79da7d042b | ||
|
|
e041e78bc7 | ||
|
|
5809fae602 | ||
|
|
8a295e806c | ||
|
|
d5d9d4bd1b | ||
|
|
5f274f1179 | ||
|
|
8c1cd41df9 | ||
|
|
fe4ad50119 | ||
|
|
bde981b522 | ||
|
|
a1d2deb6a9 | ||
|
|
10dbff2c02 | ||
|
|
68ffcda53b | ||
|
|
aeb95b02d2 | ||
|
|
2dbb984a1e | ||
|
|
88dd1b9aa4 | ||
|
|
87c4344d65 |
31
.vscode/launch.json
vendored
31
.vscode/launch.json
vendored
@@ -1,22 +1,11 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Launch (WireMock.Net.StandAlone.NETCoreApp)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build_WireMock.Net.StandAlone.NETCoreApp",
|
||||
"program": "${workspaceRoot}/examples/WireMock.Net.StandAlone.NETCoreApp/bin/Debug/netcoreapp2.0/WireMock.Net.StandAlone.NETCoreApp.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"stopAtEntry": false,
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
}
|
||||
]
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
60
CHANGELOG.md
60
CHANGELOG.md
@@ -1,3 +1,63 @@
|
||||
# 1.2.11.0 (18 May 2020)
|
||||
- [#469](https://github.com/WireMock-Net/WireMock.Net/pull/469) - Fix unhandled exception when target is unavailable [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#467](https://github.com/WireMock-Net/WireMock.Net/issues/467) - Proxy mode: Unhandled exception when target is not working [bug]
|
||||
|
||||
# 1.2.10 (17 May 2020)
|
||||
- [#456](https://github.com/WireMock-Net/WireMock.Net/pull/456) - Include Handlebars.Net.Helpers project [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#457](https://github.com/WireMock-Net/WireMock.Net/pull/457) - Kestrel Options Limits [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#455](https://github.com/WireMock-Net/WireMock.Net/issues/455) - There is no option to increase body size while proxying [bug]
|
||||
|
||||
# 1.2.9.0 (14 May 2020)
|
||||
- [#465](https://github.com/WireMock-Net/WireMock.Net/pull/465) - Fix method ResetMappingsAsync in the RestEase-AdminApi [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#464](https://github.com/WireMock-Net/WireMock.Net/issues/464) - RestClient Admin API Metadata Base Path Duplication [bug]
|
||||
|
||||
# 1.2.8.0 (04 May 2020)
|
||||
- [#463](https://github.com/WireMock-Net/WireMock.Net/pull/463) - GH161: Fix SourceLink support [bug] contributed by [gitfool](https://github.com/gitfool)
|
||||
|
||||
# 1.2.7.0 (30 April 2020)
|
||||
- [#461](https://github.com/WireMock-Net/WireMock.Net/pull/461) - Support Path in ProxyUrl contributed by [StefH](https://github.com/StefH)
|
||||
- [#459](https://github.com/WireMock-Net/WireMock.Net/issues/459) - When respond with proxy requestMessage.Url is used, not AbsoluteUrl [bug]
|
||||
|
||||
# 1.2.6.0 (29 April 2020)
|
||||
- [#460](https://github.com/WireMock-Net/WireMock.Net/pull/460) - When using ResponseMessageTransformer : keep BodyEncoding [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#458](https://github.com/WireMock-Net/WireMock.Net/issues/458) - Response BodyAsString loses BodyData.Encoding when UseTransformer = true [bug]
|
||||
|
||||
# 1.2.5.0 (17 April 2020)
|
||||
- [#454](https://github.com/WireMock-Net/WireMock.Net/pull/454) - Fix port = 0 for net452 [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#453](https://github.com/WireMock-Net/WireMock.Net/issues/453) - MockServer not starting [bug]
|
||||
|
||||
# 1.2.4.0 (10 April 2020)
|
||||
- [#439](https://github.com/WireMock-Net/WireMock.Net/pull/439) - Add support for GZip and Deflate [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#444](https://github.com/WireMock-Net/WireMock.Net/pull/444) - Add readme.md + license from mock4net [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#451](https://github.com/WireMock-Net/WireMock.Net/pull/451) - Update NuGet dependencies (e.g. coverage related) to fix CI-build [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#452](https://github.com/WireMock-Net/WireMock.Net/pull/452) - Add ValidatedNotNullAttribute (for SonarQube) [refactor] contributed by [StefH](https://github.com/StefH)
|
||||
- [#426](https://github.com/WireMock-Net/WireMock.Net/issues/426) - Add support for compressed requests, such as GZIP or DEFLATE [feature]
|
||||
|
||||
# 1.2.3.0 (01 April 2020)
|
||||
- [#449](https://github.com/WireMock-Net/WireMock.Net/pull/449) - Netstandard21 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#447](https://github.com/WireMock-Net/WireMock.Net/issues/447) - Add support for .NET Standard 2.1 / .NET Core 3.1 [feature]
|
||||
- [#448](https://github.com/WireMock-Net/WireMock.Net/issues/448) - WireMock.Net is not compatible with Microsoft.VisualStudio.Web.CodeGeneration.Design 3.1.1 [bug]
|
||||
|
||||
# 1.2.2.0 (25 March 2020)
|
||||
- [#446](https://github.com/WireMock-Net/WireMock.Net/pull/446) - When port is provided: WireMockServer still takes a random port [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#445](https://github.com/WireMock-Net/WireMock.Net/issues/445) - Port where WireMockServer listens to - v1.2x [bug]
|
||||
|
||||
# 1.2.1.0 (17 March 2020)
|
||||
- [#442](https://github.com/WireMock-Net/WireMock.Net/pull/442) - Fix Null body in handlebars transformation [bug] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.2.0.0 (14 March 2020)
|
||||
- [#417](https://github.com/WireMock-Net/WireMock.Net/pull/417) - Let the .NET core/standard WebHostBuilder use a random port [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#422](https://github.com/WireMock-Net/WireMock.Net/pull/422) - AllowOnlyDefinedHttpStatusCodeInResponse [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#379](https://github.com/WireMock-Net/WireMock.Net/issues/379) - Trusting the self signed certificate to enable SSL on dotnet core [bug]
|
||||
- [#420](https://github.com/WireMock-Net/WireMock.Net/issues/420) - Updating to 1.1.6+ breaks tests because new AllowAnyHttpStatusCodeInResponse option defaults to false [bug]
|
||||
|
||||
# 1.1.10 (05 March 2020)
|
||||
- [#427](https://github.com/WireMock-Net/WireMock.Net/pull/427) - Add UsingOptions, UsingConnect and UsingTrace [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#434](https://github.com/WireMock-Net/WireMock.Net/pull/434) - Option to disable JSON deserialization [feature] contributed by [sebastianmattar](https://github.com/sebastianmattar)
|
||||
- [#435](https://github.com/WireMock-Net/WireMock.Net/pull/435) - Also call HandlebarsRegistrationCallback when using WithCallback(..) [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#408](https://github.com/WireMock-Net/WireMock.Net/issues/408) - Intermittent threading errors with FindLogEntries [bug]
|
||||
- [#433](https://github.com/WireMock-Net/WireMock.Net/issues/433) - HandlebarsRegistrationCallback not fired [feature]
|
||||
|
||||
# 1.1.9.0 (25 February 2020)
|
||||
- [#431](https://github.com/WireMock-Net/WireMock.Net/pull/431) - Fix LinqMatcher for JSON int64 [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#425](https://github.com/WireMock-Net/WireMock.Net/issues/425) - Allow 64 bit numbers in JSON [bug]
|
||||
|
||||
@@ -4,7 +4,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.1.9</VersionPrefix>
|
||||
<VersionPrefix>1.2.11</VersionPrefix>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.1.9.0
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.2.11.0
|
||||
10
README.md
10
README.md
@@ -21,13 +21,9 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w
|
||||
| | |
|
||||
| ***Quality*** | |
|
||||
| **Build Azure** | [](https://stef.visualstudio.com/WireMock.Net/_build/latest?definitionId=7) |
|
||||
| **CodeFactor** | [](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net)
|
||||
| **Sonar Quality Gate** | [](https://sonarcloud.io/project/issues?id=wiremock) |
|
||||
| **Sonar Bugs** | [](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=BUG) |
|
||||
| **Sonar Code Smells** | [](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=CODE_SMELL) |
|
||||
| **Sonar Coverage** | [](https://sonarcloud.io/component_measures?id=wiremock&metric=coverage) |
|
||||
| **Codecov** | [](https://codecov.io/gh/WireMock-Net/WireMock.Net) |
|
||||
| **Coveralls** | [](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master) |
|
||||
| **Quality** | [](https://sonarcloud.io/project/issues?id=wiremock) [](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net) |
|
||||
| **Sonar Bugs** | [](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=BUG) [](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=CODE_SMELL) |
|
||||
| **Coverage** | [](https://sonarcloud.io/component_measures?id=wiremock&metric=coverage) [](https://codecov.io/gh/WireMock-Net/WireMock.Net) [](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master) |
|
||||
|
||||
### NuGet packages
|
||||
|
||||
|
||||
@@ -65,6 +65,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.StandAlone", "
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.RequestLogTest", "examples\WireMock.Net.Console.RequestLogTest\WireMock.Net.Console.RequestLogTest.csproj", "{A9D039B9-7509-4CF1-9EFD-87EB82998575}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Client.Net472", "examples\WireMock.Net.Client.Net472\WireMock.Net.Client.Net472.csproj", "{02082E34-DEF2-47D0-AF0B-3326FAA908CE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp3", "examples\WireMock.Net.Console.NETCoreApp3\WireMock.Net.Console.NETCoreApp3.csproj", "{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug - Sonar|Any CPU = Debug - Sonar|Any CPU
|
||||
@@ -303,6 +307,30 @@ Global
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|x64.Build.0 = Release|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|x64.ActiveCfg = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug - Sonar|x64.Build.0 = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB}.Release|x64.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -327,6 +355,8 @@ Global
|
||||
{B6269AAC-170A-4346-8B9A-579DED3D9A94} = {EF242EDF-7133-4277-9A0C-18744DE08707}
|
||||
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {EF242EDF-7133-4277-9A0C-18744DE08707}
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{02082E34-DEF2-47D0-AF0B-3326FAA908CE} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
{C54A5D32-EFE0-407B-BA8D-7172A1000DCB} = {F0C22C47-DF71-463C-9B04-B4E0F3B8708A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BF428BCC-C837-433B-87D2-15C7014B73E9}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WWW/@EntryIndexedValue">WWW</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XMS/@EntryIndexedValue">XMS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=XUA/@EntryIndexedValue">XUA</s:String>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Flurl/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=funcs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@@ -6,7 +6,7 @@ variables:
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx
|
||||
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp3.1 --logger trx
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testRunner: VSTest
|
||||
|
||||
@@ -28,11 +28,11 @@ steps:
|
||||
displayName: Begin SonarScanner
|
||||
condition: and(succeeded(), eq(variables['RUN_SONAR'], 'yes'))
|
||||
|
||||
# Build source, tests and run tests for net452 and netcoreapp2.1 (with coverage)
|
||||
# Build source, tests and run tests for net452 and netcoreapp3.1 (with coverage)
|
||||
- script: |
|
||||
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net452
|
||||
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
|
||||
displayName: 'Build source, tests and run tests for net452 and netcoreapp2.1 (with coverage)'
|
||||
dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework netcoreapp3.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
|
||||
displayName: 'Build source, tests and run tests for net452 and netcoreapp3.1 (with coverage)'
|
||||
|
||||
# End SonarScanner
|
||||
- script: |
|
||||
@@ -46,7 +46,7 @@ steps:
|
||||
|
||||
# Upload coverage to codecov.io
|
||||
- script: |
|
||||
%USERPROFILE%\.nuget\packages\codecov\1.1.0\tools\codecov.exe -f "./test/WireMock.Net.Tests/coverage.opencover.xml" -t $(CODECOV_TOKEN)
|
||||
%USERPROFILE%\.nuget\packages\codecov\1.10.0\tools\codecov.exe -f "./test/WireMock.Net.Tests/coverage.opencover.xml" -t $(CODECOV_TOKEN)
|
||||
displayName: Upload coverage to codecov.io
|
||||
|
||||
# https://github.com/microsoft/azure-pipelines-tasks/issues/12212
|
||||
|
||||
6
examples/WireMock.Net.Client.Net472/App.config
Normal file
6
examples/WireMock.Net.Client.Net472/App.config
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
</configuration>
|
||||
35
examples/WireMock.Net.Client.Net472/Program.cs
Normal file
35
examples/WireMock.Net.Client.Net472/Program.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Newtonsoft.Json;
|
||||
using RestEase;
|
||||
using System;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Client;
|
||||
|
||||
namespace WireMock.Net.Client.Net472
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
// Create an implementation of the IWireMockAdminApi and pass in the base URL for the API.
|
||||
var api = RestClient.For<IWireMockAdminApi>("http://localhost:9091");
|
||||
|
||||
// Set BASIC Auth
|
||||
var value = Convert.ToBase64String(Encoding.ASCII.GetBytes("a:b"));
|
||||
api.Authorization = new AuthenticationHeaderValue("Basic", value);
|
||||
|
||||
var settings1 = await api.GetSettingsAsync();
|
||||
Console.WriteLine($"settings1 = {JsonConvert.SerializeObject(settings1)}");
|
||||
}
|
||||
}
|
||||
|
||||
//public interface IWireMockAdminApi
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// Authentication header
|
||||
// /// </summary>
|
||||
// [Header("Authorization")]
|
||||
// AuthenticationHeaderValue Authorization { get; set; }
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
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.Client.Net472")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("mStack.nl")]
|
||||
[assembly: AssemblyProduct("WireMock.Net.Client.Net472")]
|
||||
[assembly: AssemblyCopyright("Copyright © mStack.nl 2020")]
|
||||
[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("02082e34-def2-47d0-af0b-3326faa908ce")]
|
||||
|
||||
// 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")]
|
||||
@@ -0,0 +1,83 @@
|
||||
<?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>{02082E34-DEF2-47D0-AF0B-3326FAA908CE}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>WireMock.Net.Client.Net472</RootNamespace>
|
||||
<AssemblyName>WireMock.Net.Client.Net472</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</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>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.6.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RestEase, Version=1.4.10.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RestEase.1.4.10\lib\net45\RestEase.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WireMock.Net.Abstractions, Version=1.2.0.0, Culture=neutral, PublicKeyToken=c8d65537854e1f03, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\WireMock.Net.Abstractions.1.2.0\lib\net45\WireMock.Net.Abstractions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WireMock.Net.RestClient">
|
||||
<HintPath>..\..\packages\WireMock.Net.RestClient.1.2.0\lib\net45\WireMock.Net.RestClient.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" />
|
||||
<Import Project="..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets" Condition="Exists('..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Brutal.Dev.StrongNameSigner.2.7.1\build\Brutal.Dev.StrongNameSigner.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
8
examples/WireMock.Net.Client.Net472/packages.config
Normal file
8
examples/WireMock.Net.Client.Net472/packages.config
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Brutal.Dev.StrongNameSigner" version="2.7.1" targetFramework="net472" />
|
||||
<package id="Newtonsoft.Json" version="6.0.1" targetFramework="net472" />
|
||||
<package id="RestEase" version="1.4.10" targetFramework="net472" />
|
||||
<package id="WireMock.Net.Abstractions" version="1.2.0" targetFramework="net472" />
|
||||
<package id="WireMock.Net.RestClient" version="1.2.0" targetFramework="net472" />
|
||||
</packages>
|
||||
@@ -0,0 +1,55 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net.Console.Net452.Classic\MainApp.cs" Link="MainApp.cs" />
|
||||
<Compile Include="..\WireMock.Net.Console.Net452.Classic\CustomFileSystemFileHandler.cs" Link="CustomFileSystemFileHandler.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>
|
||||
<Compile Remove="__admin\mappings\1.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="__admin\mappings\array.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="0.0.3" />
|
||||
<PackageReference Include="log4net" Version="2.0.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<!--<PackageReference Include="Microsoft.CodeAnalysis.Scripting.Common" Version="3.4.0" />-->
|
||||
</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>
|
||||
<None Update="__admin\mappings\MyXmlResponse.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1 @@
|
||||
// C# Hello
|
||||
@@ -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,22 @@
|
||||
{
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/bodyasfilexmltest",
|
||||
"IgnoreCase": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"Headers": {"Content-Type": "application/xml"},
|
||||
"BodyAsFile": "MyXmlResponse.xml",
|
||||
"UseTransformer": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<xml>
|
||||
<hello>world</hello>
|
||||
</xml>
|
||||
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"Title": "1",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/mappings_static_1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"BodyAsJson": { "result": "mappings static_1" },
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Title": "2",
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/mappings_static_2"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"BodyAsJson": { "result": "mappings static_2" },
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"WireMock.Net.StandAlone.NETCoreApp": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--Urls http://*:9091 --WireMockLogger WireMockConsoleLogger"
|
||||
}
|
||||
}
|
||||
{
|
||||
"profiles": {
|
||||
"WireMock.Net.StandAlone.NETCoreApp": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--Port 9091 --WireMockLogger WireMockConsoleLogger"
|
||||
}
|
||||
}
|
||||
}
|
||||
177
mock4net/LICENSE.txt
Normal file
177
mock4net/LICENSE.txt
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
3
mock4net/readme.md
Normal file
3
mock4net/readme.md
Normal file
@@ -0,0 +1,3 @@
|
||||
WireMock.Net is based on the source-code from https://github.com/alexvictoor/mock4net
|
||||
|
||||
The license in this folder is copied from https://github.com/alexvictoor/mock4net/blob/master/LICENSE.txt
|
||||
@@ -40,6 +40,11 @@ namespace WireMock.Admin.Requests
|
||||
/// </summary>
|
||||
public string AbsoluteUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The ProxyUrl (if a proxy is used).
|
||||
/// </summary>
|
||||
public string ProxyUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The query.
|
||||
/// </summary>
|
||||
|
||||
@@ -4,25 +4,16 @@
|
||||
<Description>Commonly used interfaces, models, enumerations and types.</Description>
|
||||
<AssemblyTitle>WireMock.Net.Abstractions</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard1.0;netstandard2.0;net45</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard1.0;netstandard2.0;netstandard2.1;net45</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.Abstractions</AssemblyName>
|
||||
<PackageId>WireMock.Net.Abstractions</PackageId>
|
||||
<PackageTags>wiremock;interfaces;models;classes;enumerations;types</PackageTags>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
<!--<DebugType>full</DebugType>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>-->
|
||||
<ProjectGuid>{B6269AAC-170A-4346-8B9A-579DED3D9A94}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
||||
@@ -33,14 +24,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
|
||||
<!--<GeneratePackageOnBuild>true</GeneratePackageOnBuild>-->
|
||||
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -86,7 +86,7 @@ namespace WireMock.Client
|
||||
/// Delete (reset) all mappings.
|
||||
/// </summary>
|
||||
/// <param name="reloadStaticMappings">A value indicating whether to reload the static mappings after the reset.</param>
|
||||
[Post("__admin/mappings/reset")]
|
||||
[Post("mappings/reset")]
|
||||
Task<StatusModel> ResetMappingsAsync(bool? reloadStaticMappings = false);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -4,25 +4,16 @@
|
||||
<Description>A RestClient using RestEase to access the admin interface.</Description>
|
||||
<AssemblyTitle>WireMock.Net.RestClient</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>netstandard1.1;netstandard2.0;net45</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard1.1;netstandard2.0;netstandard2.1;net45</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.RestClient</AssemblyName>
|
||||
<PackageId>WireMock.Net.RestClient</PackageId>
|
||||
<PackageTags>wiremock;rest;client;restclient;restease;rest;json</PackageTags>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<RootNamespace>WireMock.Client</RootNamespace>
|
||||
<!--<DebugType>full</DebugType>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>-->
|
||||
<ProjectGuid>{B6269AAC-170A-43D6-8B9A-579DED3D9A96}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
||||
@@ -33,11 +24,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
|
||||
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="RestEase" Version="1.4.10" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -3,25 +3,16 @@
|
||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.StandAlone</AssemblyName>
|
||||
<PackageId>WireMock.Net.StandAlone</PackageId>
|
||||
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<RootNamespace>WireMock.Net.StandAlone</RootNamespace>
|
||||
<!--<DebugType>full</DebugType>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>-->
|
||||
<ProjectGuid>{B6269AAC-170A-43D5-8B9A-579DED3D9A95}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<CodeAnalysisRuleSet>WireMock.Net.StandAlone.ruleset</CodeAnalysisRuleSet>
|
||||
@@ -30,13 +21,13 @@
|
||||
<!--<DelaySign>true</DelaySign>-->
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<PathMap>$(MSBuildProjectDirectory)=/</PathMap>
|
||||
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
|
||||
<DefineConstants>NETSTANDARD;USE_ASPNETCORE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -45,9 +36,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1">
|
||||
<PrivateAssets>All</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2018.2.1" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="7.8.0.7320">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace WireMock.Http
|
||||
return client;
|
||||
}
|
||||
|
||||
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url)
|
||||
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson, bool decompressGzipAndDeflate)
|
||||
{
|
||||
Check.NotNull(client, nameof(client));
|
||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||
@@ -83,7 +83,7 @@ namespace WireMock.Http
|
||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
||||
|
||||
// Create ResponseMessage
|
||||
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri);
|
||||
return await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/WireMock.Net/Http/HttpRequestMethods.cs
Normal file
18
src/WireMock.Net/Http/HttpRequestMethods.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace WireMock.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
|
||||
/// </summary>
|
||||
internal static class HttpRequestMethods
|
||||
{
|
||||
public const string CONNECT = "CONNECT";
|
||||
public const string DELETE = "DELETE";
|
||||
public const string GET = "GET";
|
||||
public const string HEAD = "HEAD";
|
||||
public const string OPTIONS = "OPTIONS";
|
||||
public const string PATCH = "PATCH";
|
||||
public const string POST = "POST";
|
||||
public const string PUT = "PUT";
|
||||
public const string TRACE = "TRACE";
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace WireMock.Http
|
||||
{
|
||||
internal static class HttpResponseMessageHelper
|
||||
{
|
||||
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri)
|
||||
public static async Task<ResponseMessage> CreateAsync(HttpResponseMessage httpResponseMessage, Uri requiredUri, Uri originalUri, bool deserializeJson, bool decompressGzipAndDeflate)
|
||||
{
|
||||
var responseMessage = new ResponseMessage { StatusCode = (int)httpResponseMessage.StatusCode };
|
||||
|
||||
@@ -24,7 +24,21 @@ namespace WireMock.Http
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
|
||||
IEnumerable<string> contentEncodingHeader = null;
|
||||
if (headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
contentEncodingHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = stream,
|
||||
ContentType = contentTypeHeader?.FirstOrDefault(),
|
||||
DeserializeJson = deserializeJson,
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = decompressGzipAndDeflate
|
||||
};
|
||||
responseMessage.BodyData = await BodyParser.Parse(bodyParserSettings);
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace WireMock.Matchers
|
||||
|
||||
object result = null;
|
||||
|
||||
#if NET451 || NET452
|
||||
#if (NET451 || NET452)
|
||||
var compilerParams = new System.CodeDom.Compiler.CompilerParameters
|
||||
{
|
||||
GenerateInMemory = true,
|
||||
@@ -122,36 +122,42 @@ namespace WireMock.Matchers
|
||||
{
|
||||
result = methodInfo.Invoke(helper, new[] { inputValue });
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper");
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to call method 'IsMatch' in WireMock.CodeHelper", ex);
|
||||
}
|
||||
}
|
||||
#elif NET46 || NET461
|
||||
#elif (NET46 || NET461)
|
||||
dynamic script;
|
||||
try
|
||||
{
|
||||
script = CSScriptLibrary.CSScript.Evaluator.CompileCode(source).CreateObject("*");
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to create compiler for WireMock.CodeHelper");
|
||||
throw new WireMockException("CSharpCodeMatcher: Unable to create compiler for WireMock.CodeHelper", ex);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
result = script.IsMatch(inputValue);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper");
|
||||
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
|
||||
}
|
||||
#elif NETSTANDARD2_0
|
||||
|
||||
#elif (NETSTANDARD2_0 || NETSTANDARD2_1)
|
||||
dynamic script;
|
||||
try
|
||||
{
|
||||
var assembly = CSScriptLib.CSScript.Evaluator.CompileCode(source);
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
script = csscript.GenericExtensions.CreateObject(assembly, "*");
|
||||
#else
|
||||
script = CSScriptLib.ReflectionExtensions.CreateObject(assembly,"*");
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -164,10 +170,10 @@ namespace WireMock.Matchers
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper");
|
||||
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
|
||||
}
|
||||
#else
|
||||
throw new NotSupportedException("The 'CSharpCodeMatcher' cannot be used in netstandard 1.3");
|
||||
throw new NotSupportedException("The 'CSharpCodeMatcher' cannot be used in netstandard 1.3");
|
||||
#endif
|
||||
try
|
||||
{
|
||||
|
||||
2
src/WireMock.Net/Matchers/Request/_mock4net-license.txt
Normal file
2
src/WireMock.Net/Matchers/Request/_mock4net-license.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Some source files in this folder are based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
40
src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard.cs
Normal file
40
src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
#if USE_ASPNETCORE && !NETSTANDARD1_3
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal partial class AspNetCoreSelfHost
|
||||
{
|
||||
private static void SetKestrelOptionsLimits(KestrelServerOptions options)
|
||||
{
|
||||
options.Limits.KeepAliveTimeout = TimeSpan.MaxValue;
|
||||
options.Limits.MaxRequestBodySize = null; // https://stackoverflow.com/questions/46738364/increase-upload-request-length-limit-in-kestrel
|
||||
options.Limits.MaxRequestBufferSize = null;
|
||||
options.Limits.MaxRequestHeaderCount = 100;
|
||||
options.Limits.MaxResponseBufferSize = null;
|
||||
options.Limits.RequestHeadersTimeout = TimeSpan.MaxValue;
|
||||
}
|
||||
|
||||
private static void SetHttpsAndUrls(KestrelServerOptions options, ICollection<(string Url, int Port)> urlDetails)
|
||||
{
|
||||
foreach (var detail in urlDetails)
|
||||
{
|
||||
if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
options.Listen(System.Net.IPAddress.Any, detail.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
32
src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard13.cs
Normal file
32
src/WireMock.Net/Owin/AspNetCoreSelfHost.NETStandard13.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
#if USE_ASPNETCORE && NETSTANDARD1_3
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel;
|
||||
using WireMock.HttpsCertificate;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal partial class AspNetCoreSelfHost
|
||||
{
|
||||
private static void SetKestrelOptionsLimits(KestrelServerOptions options)
|
||||
{
|
||||
options.Limits.KeepAliveTimeout = TimeSpan.MaxValue;
|
||||
options.Limits.MaxRequestBufferSize = null;
|
||||
options.Limits.MaxRequestHeaderCount = 100;
|
||||
options.Limits.MaxResponseBufferSize = null;
|
||||
options.Limits.RequestHeadersTimeout = TimeSpan.MaxValue;
|
||||
}
|
||||
|
||||
private static void SetHttpsAndUrls(KestrelServerOptions options, ICollection<(string Url, int Port)> urlDetails)
|
||||
{
|
||||
var urls = urlDetails.Select(u => u.Url);
|
||||
if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,170 +1,158 @@
|
||||
#if USE_ASPNETCORE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.HttpsCertificate;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Owin.Mappers;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal class AspNetCoreSelfHost : IOwinSelfHost
|
||||
{
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private readonly IWireMockMiddlewareOptions _options;
|
||||
private readonly string[] _urls;
|
||||
private readonly IWireMockLogger _logger;
|
||||
private Exception _runningException;
|
||||
|
||||
private IWebHost _host;
|
||||
|
||||
public bool IsStarted { get; private set; }
|
||||
|
||||
public List<string> Urls { get; } = new List<string>();
|
||||
|
||||
public List<int> Ports { get; } = new List<int>();
|
||||
|
||||
public Exception RunningException => _runningException;
|
||||
|
||||
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
||||
{
|
||||
Check.NotNull(options, nameof(options));
|
||||
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||
|
||||
_logger = options.Logger ?? new WireMockConsoleLogger();
|
||||
|
||||
foreach (string uriPrefix in uriPrefixes)
|
||||
{
|
||||
Urls.Add(uriPrefix);
|
||||
|
||||
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
|
||||
Ports.Add(port);
|
||||
}
|
||||
|
||||
_options = options;
|
||||
_urls = uriPrefixes;
|
||||
}
|
||||
|
||||
public Task StartAsync()
|
||||
{
|
||||
var builder = new WebHostBuilder();
|
||||
|
||||
// Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292
|
||||
// On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not
|
||||
// specified (even though we don't actually use that base path mechanism, since we have our own way of configuring
|
||||
// a filesystem handler).
|
||||
if (string.IsNullOrEmpty(AppContext.BaseDirectory))
|
||||
{
|
||||
builder.UseContentRoot(System.IO.Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
_host = builder
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton(_options);
|
||||
services.AddSingleton<IMappingMatcher, MappingMatcher>();
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
})
|
||||
.Configure(appBuilder =>
|
||||
{
|
||||
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
|
||||
appBuilder.UseMiddleware<WireMockMiddleware>();
|
||||
|
||||
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
})
|
||||
.UseKestrel(options =>
|
||||
{
|
||||
#if NETSTANDARD1_3
|
||||
if (_urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
|
||||
}
|
||||
#else
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
|
||||
foreach (string url in _urls.Where(u => u.StartsWith("http://", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
|
||||
options.Listen(System.Net.IPAddress.Any, port);
|
||||
}
|
||||
|
||||
foreach (string url in _urls.Where(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
|
||||
options.Listen(System.Net.IPAddress.Any, port, listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(); // PublicCertificateHelper.GetX509Certificate2()
|
||||
});
|
||||
}
|
||||
#endif
|
||||
})
|
||||
#if NETSTANDARD1_3
|
||||
.UseUrls(_urls)
|
||||
#endif
|
||||
.Build();
|
||||
|
||||
return RunHost(_cts.Token);
|
||||
}
|
||||
|
||||
private Task RunHost(CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime));
|
||||
appLifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
IsStarted = true;
|
||||
});
|
||||
|
||||
#if NETSTANDARD1_3
|
||||
_logger.Info("WireMock.Net server using netstandard1.3");
|
||||
#elif NETSTANDARD2_0
|
||||
_logger.Info("WireMock.Net server using netstandard2.0");
|
||||
#elif NET46
|
||||
_logger.Info("WireMock.Net server using .net 4.6.1 or higher");
|
||||
#endif
|
||||
#if NETSTANDARD1_3
|
||||
return Task.Run(() =>
|
||||
{
|
||||
_host.Run(token);
|
||||
});
|
||||
#else
|
||||
return _host.RunAsync(token);
|
||||
#endif
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_runningException = e;
|
||||
_logger.Error(e.ToString());
|
||||
|
||||
IsStarted = false;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync()
|
||||
{
|
||||
_cts.Cancel();
|
||||
|
||||
IsStarted = false;
|
||||
#if NETSTANDARD1_3
|
||||
return Task.FromResult(true);
|
||||
#else
|
||||
return _host.StopAsync();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#if USE_ASPNETCORE
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Owin.Mappers;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal partial class AspNetCoreSelfHost : IOwinSelfHost
|
||||
{
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private readonly IWireMockMiddlewareOptions _options;
|
||||
private readonly IWireMockLogger _logger;
|
||||
private readonly HostUrlOptions _urlOptions;
|
||||
|
||||
private Exception _runningException;
|
||||
private IWebHost _host;
|
||||
|
||||
public bool IsStarted { get; private set; }
|
||||
|
||||
public List<string> Urls { get; } = new List<string>();
|
||||
|
||||
public List<int> Ports { get; } = new List<int>();
|
||||
|
||||
public Exception RunningException => _runningException;
|
||||
|
||||
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
|
||||
{
|
||||
Check.NotNull(options, nameof(options));
|
||||
Check.NotNull(urlOptions, nameof(urlOptions));
|
||||
|
||||
_logger = options.Logger ?? new WireMockConsoleLogger();
|
||||
|
||||
_options = options;
|
||||
_urlOptions = urlOptions;
|
||||
}
|
||||
|
||||
public Task StartAsync()
|
||||
{
|
||||
var builder = new WebHostBuilder();
|
||||
|
||||
// Workaround for https://github.com/WireMock-Net/WireMock.Net/issues/292
|
||||
// On some platforms, AppContext.BaseDirectory is null, which causes WebHostBuilder to fail if ContentRoot is not
|
||||
// specified (even though we don't actually use that base path mechanism, since we have our own way of configuring
|
||||
// a filesystem handler).
|
||||
if (string.IsNullOrEmpty(AppContext.BaseDirectory))
|
||||
{
|
||||
builder.UseContentRoot(System.IO.Directory.GetCurrentDirectory());
|
||||
}
|
||||
|
||||
_host = builder
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddSingleton(_options);
|
||||
services.AddSingleton<IMappingMatcher, MappingMatcher>();
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
})
|
||||
.Configure(appBuilder =>
|
||||
{
|
||||
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
|
||||
appBuilder.UseMiddleware<WireMockMiddleware>();
|
||||
|
||||
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
|
||||
})
|
||||
.UseKestrel(options =>
|
||||
{
|
||||
SetKestrelOptionsLimits(options);
|
||||
|
||||
SetHttpsAndUrls(options, _urlOptions.GetDetails());
|
||||
})
|
||||
|
||||
#if NETSTANDARD1_3
|
||||
.UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
|
||||
#endif
|
||||
.Build();
|
||||
|
||||
return RunHost(_cts.Token);
|
||||
}
|
||||
|
||||
private Task RunHost(CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var appLifetime = (IApplicationLifetime)_host.Services.GetService(typeof(IApplicationLifetime));
|
||||
appLifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
var addresses = _host.ServerFeatures
|
||||
.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>()
|
||||
.Addresses;
|
||||
|
||||
foreach (string address in addresses)
|
||||
{
|
||||
Urls.Add(address.Replace("0.0.0.0", "localhost"));
|
||||
|
||||
PortUtils.TryExtract(address, out string protocol, out string host, out int port);
|
||||
Ports.Add(port);
|
||||
}
|
||||
|
||||
IsStarted = true;
|
||||
});
|
||||
|
||||
#if NETSTANDARD1_3
|
||||
_logger.Info("WireMock.Net server using netstandard1.3");
|
||||
#elif NETSTANDARD2_0
|
||||
_logger.Info("WireMock.Net server using netstandard2.0");
|
||||
#elif NETSTANDARD2_1
|
||||
_logger.Info("WireMock.Net server using netstandard2.1");
|
||||
#elif NET46
|
||||
_logger.Info("WireMock.Net server using .net 4.6.1 or higher");
|
||||
#endif
|
||||
|
||||
#if NETSTANDARD1_3
|
||||
return Task.Run(() =>
|
||||
{
|
||||
_host.Run(token);
|
||||
});
|
||||
#else
|
||||
return _host.RunAsync(token);
|
||||
#endif
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_runningException = e;
|
||||
_logger.Error(e.ToString());
|
||||
|
||||
IsStarted = false;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task StopAsync()
|
||||
{
|
||||
_cts.Cancel();
|
||||
|
||||
IsStarted = false;
|
||||
#if NETSTANDARD1_3
|
||||
return Task.FromResult(true);
|
||||
#else
|
||||
return _host.StopAsync();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
43
src/WireMock.Net/Owin/HostUrlOptions.cs
Normal file
43
src/WireMock.Net/Owin/HostUrlOptions.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Owin
|
||||
{
|
||||
internal class HostUrlOptions
|
||||
{
|
||||
public ICollection<string> Urls { get; set; }
|
||||
|
||||
public int? Port { get; set; }
|
||||
|
||||
public bool UseSSL { get; set; }
|
||||
|
||||
public ICollection<(string Url, int Port)> GetDetails()
|
||||
{
|
||||
var list = new List<(string Url, int Port)>();
|
||||
if (Urls == null)
|
||||
{
|
||||
int port = Port > 0 ? Port.Value : FindFreeTcpPort();
|
||||
list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port));
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string url in Urls)
|
||||
{
|
||||
PortUtils.TryExtract(url, out string protocol, out string host, out int port);
|
||||
list.Add((url, port));
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private int FindFreeTcpPort()
|
||||
{
|
||||
#if USE_ASPNETCORE || NETSTANDARD2_0 || NETSTANDARD2_1
|
||||
return 0;
|
||||
#else
|
||||
return PortUtils.FindFreeTcpPort();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,10 @@ namespace WireMock.Owin
|
||||
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
bool? DisableJsonBodyParsing { get; set; }
|
||||
|
||||
bool? DisableRequestBodyDecompressing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Http;
|
||||
using WireMock.Models;
|
||||
using WireMock.Util;
|
||||
#if !USE_ASPNETCORE
|
||||
@@ -27,12 +28,18 @@ namespace WireMock.Owin.Mappers
|
||||
string method = request.Method;
|
||||
|
||||
Dictionary<string, string[]> headers = null;
|
||||
IEnumerable<string> contentEncodingHeader = null;
|
||||
if (request.Headers.Any())
|
||||
{
|
||||
headers = new Dictionary<string, string[]>();
|
||||
foreach (var header in request.Headers)
|
||||
{
|
||||
headers.Add(header.Key, header.Value);
|
||||
|
||||
if (string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
contentEncodingHeader = header.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +56,15 @@ namespace WireMock.Owin.Mappers
|
||||
BodyData body = null;
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
|
||||
{
|
||||
body = await BodyParser.Parse(request.Body, request.ContentType);
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = request.Body,
|
||||
ContentType = request.ContentType,
|
||||
DeserializeJson = !options.DisableJsonBodyParsing.GetValueOrDefault(false),
|
||||
ContentEncoding = contentEncodingHeader?.FirstOrDefault(),
|
||||
DecompressGZipAndDeflate = !options.DisableRequestBodyDecompressing.GetValueOrDefault(false)
|
||||
};
|
||||
body = await BodyParser.Parse(bodyParserSettings);
|
||||
}
|
||||
|
||||
return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.UtcNow };
|
||||
|
||||
@@ -104,12 +104,12 @@ namespace WireMock.Owin.Mappers
|
||||
|
||||
private int MapStatusCode(int code)
|
||||
{
|
||||
if (_options.AllowAnyHttpStatusCodeInResponse == true || Enum.IsDefined(typeof(HttpStatusCode), code))
|
||||
if (_options.AllowOnlyDefinedHttpStatusCodeInResponse == true && !Enum.IsDefined(typeof(HttpStatusCode), code))
|
||||
{
|
||||
return code;
|
||||
return (int)HttpStatusCode.OK;
|
||||
}
|
||||
|
||||
return (int)HttpStatusCode.OK;
|
||||
return code;
|
||||
}
|
||||
|
||||
private bool IsFault(ResponseMessage responseMessage)
|
||||
|
||||
@@ -8,7 +8,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Owin.Mappers;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Owin
|
||||
@@ -18,24 +17,22 @@ namespace WireMock.Owin
|
||||
private readonly IWireMockMiddlewareOptions _options;
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private readonly IWireMockLogger _logger;
|
||||
|
||||
private Exception _runningException;
|
||||
|
||||
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] params string[] uriPrefixes)
|
||||
public OwinSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
|
||||
{
|
||||
Check.NotNull(options, nameof(options));
|
||||
Check.NotNullOrEmpty(uriPrefixes, nameof(uriPrefixes));
|
||||
|
||||
_logger = options.Logger ?? new WireMockConsoleLogger();
|
||||
|
||||
foreach (string uriPrefix in uriPrefixes)
|
||||
{
|
||||
Urls.Add(uriPrefix);
|
||||
|
||||
PortUtils.TryExtract(uriPrefix, out string protocol, out string host, out int port);
|
||||
Ports.Add(port);
|
||||
}
|
||||
Check.NotNull(urlOptions, nameof(urlOptions));
|
||||
|
||||
_options = options;
|
||||
_logger = options.Logger ?? new WireMockConsoleLogger();
|
||||
|
||||
foreach (var detail in urlOptions.GetDetails())
|
||||
{
|
||||
Urls.Add(detail.Url);
|
||||
Ports.Add(detail.Port);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsStarted { get; private set; }
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace WireMock.Owin
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Error($"Providing a Response for Mapping '{result?.Mapping?.Guid}' failed. HttpStatusCode set to 500. Exception: {ex}");
|
||||
response = ResponseMessageBuilder.Create(JsonConvert.SerializeObject(ex), 500);
|
||||
response = ResponseMessageBuilder.Create(ex.Message, 500);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -43,7 +43,13 @@ namespace WireMock.Owin
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowBodyForAllHttpMethods"/>
|
||||
public bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowAnyHttpStatusCodeInResponse"/>
|
||||
public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowOnlyDefinedHttpStatusCodeInResponse"/>
|
||||
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableJsonBodyParsing"/>
|
||||
public bool? DisableJsonBodyParsing { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.DisableRequestBodyDecompressing"/>
|
||||
public bool? DisableRequestBodyDecompressing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,13 @@ namespace WireMock.RequestBuilders
|
||||
/// </summary>
|
||||
public interface IMethodRequestBuilder : IHeadersRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// UsingConnect: add HTTP Method matching on `CONNECT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingDelete: add HTTP Method matching on `DELETE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
@@ -24,7 +31,7 @@ namespace WireMock.RequestBuilders
|
||||
IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
|
||||
/// UsingHead: Add HTTP Method matching on `HEAD` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
@@ -44,6 +51,13 @@ namespace WireMock.RequestBuilders
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `OPTIONS` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingPut: add HTTP Method matching on `PUT` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
@@ -51,6 +65,13 @@ namespace WireMock.RequestBuilders
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingTrace: add HTTP Method matching on `TRACE` and matchBehaviour (optional).
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
/// <summary>
|
||||
/// UsingAnyMethod: add HTTP Method matching on any method.
|
||||
/// </summary>
|
||||
|
||||
115
src/WireMock.Net/RequestBuilders/Request.UsingMethods.cs
Normal file
115
src/WireMock.Net/RequestBuilders/Request.UsingMethods.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System.Linq;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingConnect(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingConnect(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.CONNECT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.DELETE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.GET));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.HEAD));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingOptions(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingOptions(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.OPTIONS));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.POST));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PATCH));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.PUT));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingTrace(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingTrace(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, HttpRequestMethods.TRACE));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
|
||||
public IRequestBuilder UsingAnyMethod()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
_requestMatchers.Remove(matcher);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
|
||||
public IRequestBuilder UsingAnyVerb()
|
||||
{
|
||||
return UsingAnyMethod();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
|
||||
public IRequestBuilder UsingMethod(params string[] methods)
|
||||
{
|
||||
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
|
||||
public IRequestBuilder UsingVerb(params string[] verbs)
|
||||
{
|
||||
return UsingMethod(verbs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
|
||||
{
|
||||
Check.NotNullOrEmpty(methods, nameof(methods));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +1,75 @@
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
|
||||
public IRequestBuilder WithBody(IMatcher matcher)
|
||||
{
|
||||
return WithBody(new[] { matcher });
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
|
||||
public IRequestBuilder WithBody(IMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>
|
||||
public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
|
||||
public IRequestBuilder WithBody(IMatcher matcher)
|
||||
{
|
||||
return WithBody(new[] { matcher });
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher[])"/>
|
||||
public IRequestBuilder WithBody(IMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(matchers, nameof(matchers));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(matchers));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
@@ -151,86 +153,5 @@ namespace WireMock.RequestBuilders
|
||||
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "DELETE"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "GET"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "HEAD"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "POST"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PATCH"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>
|
||||
public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "PUT"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>
|
||||
public IRequestBuilder UsingAnyMethod()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
_requestMatchers.Remove(matcher);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
|
||||
public IRequestBuilder UsingAnyVerb()
|
||||
{
|
||||
return UsingAnyMethod();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>
|
||||
public IRequestBuilder UsingMethod(params string[] methods)
|
||||
{
|
||||
return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>
|
||||
public IRequestBuilder UsingVerb(params string[] verbs)
|
||||
{
|
||||
return UsingMethod(verbs);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>
|
||||
public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)
|
||||
{
|
||||
Check.NotNullOrEmpty(methods, nameof(methods));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using JetBrains.Annotations;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -30,6 +32,11 @@ namespace WireMock
|
||||
/// </summary>
|
||||
public string AbsoluteUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The ProxyUrl (if a proxy is used).
|
||||
/// </summary>
|
||||
public string ProxyUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DateTime.
|
||||
/// </summary>
|
||||
@@ -110,6 +117,11 @@ namespace WireMock
|
||||
/// </summary>
|
||||
public string DetectedBodyTypeFromContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
public string DetectedCompression { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Host
|
||||
/// </summary>
|
||||
@@ -168,6 +180,7 @@ namespace WireMock
|
||||
BodyAsBytes = BodyData?.BodyAsBytes;
|
||||
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
|
||||
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
|
||||
DetectedCompression = BodyData?.DetectedCompression;
|
||||
|
||||
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||
Cookies = cookies;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Net;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.ResponseBuilders
|
||||
{
|
||||
@@ -9,6 +10,7 @@ namespace WireMock.ResponseBuilders
|
||||
{
|
||||
/// <summary>
|
||||
/// The with status code.
|
||||
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
@@ -16,6 +18,7 @@ namespace WireMock.ResponseBuilders
|
||||
|
||||
/// <summary>
|
||||
/// The with status code.
|
||||
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
@@ -23,6 +26,7 @@ namespace WireMock.ResponseBuilders
|
||||
|
||||
/// <summary>
|
||||
/// The with status code.
|
||||
/// By default all status codes are allowed, to change this behaviour, see <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>.
|
||||
/// </summary>
|
||||
/// <param name="code">The code.</param>
|
||||
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Http;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
@@ -341,47 +341,64 @@ namespace WireMock.ResponseBuilders
|
||||
await Task.Delay(Delay.Value);
|
||||
}
|
||||
|
||||
if (Callback != null)
|
||||
if (ProxyUrl != null && _httpClientForProxy != null)
|
||||
{
|
||||
var callbackResponseMessage = Callback(requestMessage);
|
||||
string RemoveFirstOccurrence(string source, string find)
|
||||
{
|
||||
int place = source.IndexOf(find, StringComparison.OrdinalIgnoreCase);
|
||||
return place >= 0 ? source.Remove(place, find.Length) : source;
|
||||
}
|
||||
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
|
||||
// Build the proxy url and skip duplicates
|
||||
string extra = RemoveFirstOccurrence(requestUri.LocalPath.TrimEnd('/'), new Uri(ProxyUrl).LocalPath.TrimEnd('/'));
|
||||
requestMessage.ProxyUrl = ProxyUrl + extra + requestUri.Query;
|
||||
|
||||
return await HttpClientHelper.SendAsync(
|
||||
_httpClientForProxy,
|
||||
requestMessage,
|
||||
requestMessage.ProxyUrl,
|
||||
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
|
||||
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
|
||||
);
|
||||
}
|
||||
|
||||
ResponseMessage responseMessage;
|
||||
if (Callback == null)
|
||||
{
|
||||
responseMessage = ResponseMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
responseMessage = Callback(requestMessage);
|
||||
|
||||
if (!WithCallbackUsed)
|
||||
{
|
||||
// Copy StatusCode from ResponseMessage
|
||||
callbackResponseMessage.StatusCode = ResponseMessage.StatusCode;
|
||||
responseMessage.StatusCode = ResponseMessage.StatusCode;
|
||||
|
||||
// Copy Headers from ResponseMessage (if defined)
|
||||
if (ResponseMessage.Headers != null)
|
||||
{
|
||||
callbackResponseMessage.Headers = ResponseMessage.Headers;
|
||||
responseMessage.Headers = ResponseMessage.Headers;
|
||||
}
|
||||
}
|
||||
|
||||
return callbackResponseMessage;
|
||||
}
|
||||
|
||||
if (ProxyUrl != null && _httpClientForProxy != null)
|
||||
{
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
var proxyUri = new Uri(ProxyUrl);
|
||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||
|
||||
return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
||||
}
|
||||
|
||||
if (UseTransformer)
|
||||
{
|
||||
var factory = new HandlebarsContextFactory(settings.FileSystemHandler, settings.HandlebarsRegistrationCallback);
|
||||
var responseMessageTransformer = new ResponseMessageTransformer(factory);
|
||||
return responseMessageTransformer.Transform(requestMessage, ResponseMessage, UseTransformerForBodyAsFile);
|
||||
return responseMessageTransformer.Transform(requestMessage, responseMessage, UseTransformerForBodyAsFile);
|
||||
}
|
||||
|
||||
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
|
||||
{
|
||||
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(ResponseMessage.BodyData.BodyAsFile);
|
||||
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
|
||||
}
|
||||
|
||||
return ResponseMessage;
|
||||
return responseMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Types;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using JetBrains.Annotations;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using JetBrains.Annotations;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Settings;
|
||||
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Types;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Util;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Serialization
|
||||
{
|
||||
@@ -20,6 +19,7 @@ namespace WireMock.Serialization
|
||||
AbsolutePath = logEntry.RequestMessage.AbsolutePath,
|
||||
Url = logEntry.RequestMessage.Url,
|
||||
AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
|
||||
ProxyUrl = logEntry.RequestMessage.ProxyUrl,
|
||||
Query = logEntry.RequestMessage.Query,
|
||||
Method = logEntry.RequestMessage.Method,
|
||||
Headers = logEntry.RequestMessage.Headers,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
@@ -275,7 +275,13 @@ namespace WireMock.Server
|
||||
var proxyUri = new Uri(settings.ProxyAndRecordSettings.Url);
|
||||
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
|
||||
|
||||
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
|
||||
var responseMessage = await HttpClientHelper.SendAsync(
|
||||
_httpClientForProxy,
|
||||
requestMessage,
|
||||
proxyUriWithRequestPathAndQuery.AbsoluteUri,
|
||||
!settings.DisableJsonBodyParsing.GetValueOrDefault(false),
|
||||
!settings.DisableRequestBodyDecompressing.GetValueOrDefault(false)
|
||||
);
|
||||
|
||||
if (HttpStatusRangeParser.IsMatch(settings.ProxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||
(settings.ProxyAndRecordSettings.SaveMapping || settings.ProxyAndRecordSettings.SaveMappingToFile))
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Handlers;
|
||||
@@ -17,7 +19,6 @@ using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Serialization;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Server
|
||||
@@ -202,31 +203,37 @@ namespace WireMock.Server
|
||||
_settings.Logger.Info("WireMock.Net by Stef Heyenrath (https://github.com/WireMock-Net/WireMock.Net)");
|
||||
_settings.Logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented));
|
||||
|
||||
HostUrlOptions urlOptions;
|
||||
if (settings.Urls != null)
|
||||
{
|
||||
Urls = settings.Urls.ToArray();
|
||||
urlOptions = new HostUrlOptions
|
||||
{
|
||||
Urls = settings.Urls
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
int port = settings.Port > 0 ? settings.Port.Value : PortUtils.FindFreeTcpPort();
|
||||
Urls = new[] { $"{(settings.UseSSL == true ? "https" : "http")}://localhost:{port}" };
|
||||
urlOptions = new HostUrlOptions
|
||||
{
|
||||
UseSSL = settings.UseSSL == true,
|
||||
Port = settings.Port
|
||||
};
|
||||
}
|
||||
|
||||
_options.FileSystemHandler = _settings.FileSystemHandler;
|
||||
_options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
|
||||
_options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
|
||||
_options.PreWireMockMiddlewareInit = _settings.PreWireMockMiddlewareInit;
|
||||
_options.PostWireMockMiddlewareInit = _settings.PostWireMockMiddlewareInit;
|
||||
_options.Logger = _settings.Logger;
|
||||
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
|
||||
|
||||
_matcherMapper = new MatcherMapper(_settings);
|
||||
_mappingConverter = new MappingConverter(_matcherMapper);
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
_httpServer = new AspNetCoreSelfHost(_options, Urls);
|
||||
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
|
||||
#else
|
||||
_httpServer = new OwinSelfHost(_options, Urls);
|
||||
_httpServer = new OwinSelfHost(_options, urlOptions);
|
||||
#endif
|
||||
Ports = _httpServer.Ports;
|
||||
|
||||
var startTask = _httpServer.StartAsync();
|
||||
|
||||
using (var ctsStartTimeout = new CancellationTokenSource(settings.StartTimeout))
|
||||
@@ -253,6 +260,9 @@ namespace WireMock.Server
|
||||
|
||||
ctsStartTimeout.Token.WaitHandle.WaitOne(ServerStartDelayInMs);
|
||||
}
|
||||
|
||||
Urls = _httpServer.Urls.ToArray();
|
||||
Ports = _httpServer.Ports;
|
||||
}
|
||||
|
||||
if (settings.AllowBodyForAllHttpMethods == true)
|
||||
@@ -261,10 +271,10 @@ namespace WireMock.Server
|
||||
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to True");
|
||||
}
|
||||
|
||||
if (settings.AllowAnyHttpStatusCodeInResponse == true)
|
||||
if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true)
|
||||
{
|
||||
_options.AllowAnyHttpStatusCodeInResponse = _settings.AllowAnyHttpStatusCodeInResponse;
|
||||
_settings.Logger.Info("AllowAnyHttpStatusCodeInResponse is set to True");
|
||||
_options.AllowOnlyDefinedHttpStatusCodeInResponse = _settings.AllowOnlyDefinedHttpStatusCodeInResponse;
|
||||
_settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True");
|
||||
}
|
||||
|
||||
if (settings.AllowPartialMapping == true)
|
||||
|
||||
@@ -1,147 +1,161 @@
|
||||
using System;
|
||||
using HandlebarsDotNet;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// IWireMockServerSettings
|
||||
/// </summary>
|
||||
public interface IWireMockServerSettings
|
||||
{
|
||||
/// <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 whether 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>
|
||||
/// A value indicating whether subdirectories within the static mappings path should be monitored.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? WatchStaticMappingsInSubdirectories { 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to read and write static mapping files.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which can be used to add additional Handlebars registrations. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
Action<IHandlebars, IFileSystemHandler> HandlebarsRegistrationCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? AllowCSharpCodeMatcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow a Body for all HTTP Methods. (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow any HttpStatusCode in the response. Also null, 0, empty or invalid. (default set to false).
|
||||
/// </summary>
|
||||
/// [PublicAPI]
|
||||
bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
}
|
||||
using System;
|
||||
using HandlebarsDotNet;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// IWireMockServerSettings
|
||||
/// </summary>
|
||||
public interface IWireMockServerSettings
|
||||
{
|
||||
/// <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 whether 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>
|
||||
/// A value indicating whether subdirectories within the static mappings path should be monitored.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? WatchStaticMappingsInSubdirectories { 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Handler to interact with the file system to read and write static mapping files.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Action which can be used to add additional Handlebars registrations. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
Action<IHandlebars, IFileSystemHandler> HandlebarsRegistrationCallback { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? AllowCSharpCodeMatcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow a Body for all HTTP Methods. (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow only a HttpStatus Code in the response which is defined. (default set to false).
|
||||
/// - false : also null, 0, empty or invalid HttpStatus codes are allowed.
|
||||
/// - true : only codes defined in <see cref="System.Net.HttpStatusCode"/> are allowed.
|
||||
/// </summary>
|
||||
/// [PublicAPI]
|
||||
bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Set to true to disable Json deserialization when processing requests. (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? DisableJsonBodyParsing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Disable support for GZip and Deflate request body decompression. (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? DisableRequestBodyDecompressing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,16 @@ namespace WireMock.Settings
|
||||
[PublicAPI]
|
||||
public bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.AllowAnyHttpStatusCodeInResponse"/>
|
||||
public bool? AllowAnyHttpStatusCodeInResponse { get; set; }
|
||||
/// <inheritdoc cref="IWireMockServerSettings.AllowOnlyDefinedHttpStatusCodeInResponse"/>
|
||||
[PublicAPI]
|
||||
public bool? AllowOnlyDefinedHttpStatusCodeInResponse { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.DisableJsonBodyParsing"/>
|
||||
[PublicAPI]
|
||||
public bool? DisableJsonBodyParsing { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.DisableRequestBodyDecompressing"/>
|
||||
[PublicAPI]
|
||||
public bool? DisableRequestBodyDecompressing { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ namespace WireMock.Settings
|
||||
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
|
||||
AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"),
|
||||
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods"),
|
||||
AllowAnyHttpStatusCodeInResponse = parser.GetBoolValue("AllowAnyHttpStatusCodeInResponse")
|
||||
AllowOnlyDefinedHttpStatusCodeInResponse = parser.GetBoolValue("AllowOnlyDefinedHttpStatusCodeInResponse"),
|
||||
DisableJsonBodyParsing = parser.GetBoolValue("DisableJsonBodyParsing")
|
||||
};
|
||||
|
||||
if (logger != null)
|
||||
|
||||
@@ -5,7 +5,7 @@ using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsFile
|
||||
internal static class HandlebarsFile
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext, IFileSystemHandler fileSystemHandler)
|
||||
{
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using HandlebarsDotNet;
|
||||
using WireMock.Handlers;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandlebarsHelpers
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext, IFileSystemHandler fileSystemHandler)
|
||||
{
|
||||
HandleBarsRegex.Register(handlebarsContext);
|
||||
|
||||
HandleBarsJsonPath.Register(handlebarsContext);
|
||||
|
||||
HandleBarsLinq.Register(handlebarsContext);
|
||||
|
||||
HandleBarsRandom.Register(handlebarsContext);
|
||||
|
||||
HandleBarsXeger.Register(handlebarsContext);
|
||||
|
||||
HandleBarsXPath.Register(handlebarsContext);
|
||||
|
||||
HandleBarsFile.Register(handlebarsContext, fileSystemHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsJsonPath
|
||||
internal static class HandlebarsJsonPath
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsLinq
|
||||
internal static class HandlebarsLinq
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsRandom
|
||||
internal static class HandlebarsRandom
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsRegex
|
||||
internal static class HandlebarsRegex
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ using Wmhelp.XPath2;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsXPath
|
||||
internal static class HandlebarsXPath
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext)
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsXeger
|
||||
internal static class HandlebarsXeger
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace WireMock.Transformers
|
||||
{
|
||||
var handlebars = Handlebars.Create(HandlebarsConfiguration);
|
||||
|
||||
HandlebarsHelpers.Register(handlebars, _fileSystemHandler);
|
||||
WireMockHandlebarsHelpers.Register(handlebars, _fileSystemHandler);
|
||||
|
||||
_action?.Invoke(handlebars, _fileSystemHandler);
|
||||
|
||||
|
||||
@@ -1,233 +1,236 @@
|
||||
using HandlebarsDotNet;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal class ResponseMessageTransformer
|
||||
{
|
||||
private readonly IHandlebarsContextFactory _factory;
|
||||
|
||||
public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
|
||||
{
|
||||
Check.NotNull(factory, nameof(factory));
|
||||
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var handlebarsContext = _factory.Create();
|
||||
|
||||
var responseMessage = new ResponseMessage();
|
||||
|
||||
var template = new { request = requestMessage };
|
||||
|
||||
switch (original.BodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
|
||||
TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
responseMessage.FaultType = original.FaultType;
|
||||
responseMessage.FaultPercentage = original.FaultPercentage;
|
||||
|
||||
// Headers
|
||||
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
||||
foreach (var header in original.Headers)
|
||||
{
|
||||
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
|
||||
var templateHeaderValues = header.Value
|
||||
.Select(handlebarsContext.Handlebars.Compile)
|
||||
.Select(func => func(template))
|
||||
.ToArray();
|
||||
|
||||
newHeaders.Add(templateHeaderKey(template), new WireMockList<string>(templateHeaderValues));
|
||||
}
|
||||
|
||||
responseMessage.Headers = newHeaders;
|
||||
|
||||
switch (original.StatusCode)
|
||||
{
|
||||
case int statusCodeAsInteger:
|
||||
responseMessage.StatusCode = statusCodeAsInteger;
|
||||
break;
|
||||
|
||||
case string statusCodeAsString:
|
||||
var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString);
|
||||
responseMessage.StatusCode = templateForStatusCode(template);
|
||||
break;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
JToken jToken;
|
||||
switch (original.BodyData.BodyAsJson)
|
||||
{
|
||||
case JObject bodyAsJObject:
|
||||
jToken = bodyAsJObject.DeepClone();
|
||||
WalkNode(handlebarsContext, jToken, template);
|
||||
break;
|
||||
|
||||
case Array bodyAsArray:
|
||||
jToken = JArray.FromObject(bodyAsArray);
|
||||
WalkNode(handlebarsContext, jToken, template);
|
||||
break;
|
||||
|
||||
case string bodyAsString:
|
||||
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template);
|
||||
break;
|
||||
|
||||
default:
|
||||
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
|
||||
WalkNode(handlebarsContext, jToken, template);
|
||||
break;
|
||||
}
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsJson = jToken
|
||||
};
|
||||
}
|
||||
|
||||
private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context)
|
||||
{
|
||||
var templateForStringValue = handlebarsContext.Compile(stringValue);
|
||||
string transformedString = templateForStringValue(context);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
const string property = "_";
|
||||
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
|
||||
JToken node = dummy[property];
|
||||
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
|
||||
return dummy[property];
|
||||
}
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child.Value, context);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child, context);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.String)
|
||||
{
|
||||
// In case of string, try to transform the value.
|
||||
string stringValue = node.Value<string>();
|
||||
if (string.IsNullOrEmpty(stringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var templateForStringValue = handlebarsContext.Compile(stringValue);
|
||||
string transformedString = templateForStringValue(context);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReplaceNodeValue(JToken node, string stringValue)
|
||||
{
|
||||
if (bool.TryParse(stringValue, out bool valueAsBoolean))
|
||||
{
|
||||
node.Replace(valueAsBoolean);
|
||||
return;
|
||||
}
|
||||
|
||||
JToken value;
|
||||
try
|
||||
{
|
||||
// Try to convert this string into a JsonObject
|
||||
value = JToken.Parse(stringValue);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and just keep string value and convert to JToken
|
||||
value = stringValue;
|
||||
}
|
||||
|
||||
node.Replace(value);
|
||||
}
|
||||
|
||||
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = templateBodyAsString(template)
|
||||
};
|
||||
}
|
||||
|
||||
private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
|
||||
string transformedBodyAsFilename = templateBodyAsFile(template);
|
||||
|
||||
if (!useTransformerForBodyAsFile)
|
||||
{
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
|
||||
var templateBodyAsString = handlebarsContext.Handlebars.Compile(text);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = templateBodyAsString(template),
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
using HandlebarsDotNet;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal class ResponseMessageTransformer
|
||||
{
|
||||
private readonly IHandlebarsContextFactory _factory;
|
||||
|
||||
public ResponseMessageTransformer([NotNull] IHandlebarsContextFactory factory)
|
||||
{
|
||||
Check.NotNull(factory, nameof(factory));
|
||||
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var handlebarsContext = _factory.Create();
|
||||
|
||||
var responseMessage = new ResponseMessage();
|
||||
|
||||
var template = new { request = requestMessage };
|
||||
|
||||
switch (original.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
TransformBodyAsFile(handlebarsContext, template, original, responseMessage, useTransformerForBodyAsFile);
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
|
||||
TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
responseMessage.FaultType = original.FaultType;
|
||||
responseMessage.FaultPercentage = original.FaultPercentage;
|
||||
|
||||
// Headers
|
||||
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
||||
foreach (var header in original.Headers)
|
||||
{
|
||||
var templateHeaderKey = handlebarsContext.Handlebars.Compile(header.Key);
|
||||
var templateHeaderValues = header.Value
|
||||
.Select(handlebarsContext.Handlebars.Compile)
|
||||
.Select(func => func(template))
|
||||
.ToArray();
|
||||
|
||||
newHeaders.Add(templateHeaderKey(template), new WireMockList<string>(templateHeaderValues));
|
||||
}
|
||||
|
||||
responseMessage.Headers = newHeaders;
|
||||
|
||||
switch (original.StatusCode)
|
||||
{
|
||||
case int statusCodeAsInteger:
|
||||
responseMessage.StatusCode = statusCodeAsInteger;
|
||||
break;
|
||||
|
||||
case string statusCodeAsString:
|
||||
var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString);
|
||||
responseMessage.StatusCode = templateForStatusCode(template);
|
||||
break;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
JToken jToken;
|
||||
switch (original.BodyData.BodyAsJson)
|
||||
{
|
||||
case JObject bodyAsJObject:
|
||||
jToken = bodyAsJObject.DeepClone();
|
||||
WalkNode(handlebarsContext, jToken, template);
|
||||
break;
|
||||
|
||||
case Array bodyAsArray:
|
||||
jToken = JArray.FromObject(bodyAsArray);
|
||||
WalkNode(handlebarsContext, jToken, template);
|
||||
break;
|
||||
|
||||
case string bodyAsString:
|
||||
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template);
|
||||
break;
|
||||
|
||||
default:
|
||||
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
|
||||
WalkNode(handlebarsContext, jToken, template);
|
||||
break;
|
||||
}
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = original.BodyData.Encoding,
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsJson = jToken
|
||||
};
|
||||
}
|
||||
|
||||
private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context)
|
||||
{
|
||||
var templateForStringValue = handlebarsContext.Compile(stringValue);
|
||||
string transformedString = templateForStringValue(context);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
const string property = "_";
|
||||
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
|
||||
JToken node = dummy[property];
|
||||
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
|
||||
return dummy[property];
|
||||
}
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child.Value, context);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child, context);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.String)
|
||||
{
|
||||
// In case of string, try to transform the value.
|
||||
string stringValue = node.Value<string>();
|
||||
if (string.IsNullOrEmpty(stringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var templateForStringValue = handlebarsContext.Compile(stringValue);
|
||||
string transformedString = templateForStringValue(context);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReplaceNodeValue(JToken node, string stringValue)
|
||||
{
|
||||
if (bool.TryParse(stringValue, out bool valueAsBoolean))
|
||||
{
|
||||
node.Replace(valueAsBoolean);
|
||||
return;
|
||||
}
|
||||
|
||||
JToken value;
|
||||
try
|
||||
{
|
||||
// Try to convert this string into a JsonObject
|
||||
value = JToken.Parse(stringValue);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and just keep string value and convert to JToken
|
||||
value = stringValue;
|
||||
}
|
||||
|
||||
node.Replace(value);
|
||||
}
|
||||
|
||||
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = original.BodyData.Encoding,
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = templateBodyAsString(template)
|
||||
};
|
||||
}
|
||||
|
||||
private void TransformBodyAsFile(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var templateBodyAsFile = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsFile);
|
||||
string transformedBodyAsFilename = templateBodyAsFile(template);
|
||||
|
||||
if (!useTransformerForBodyAsFile)
|
||||
{
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
|
||||
var templateBodyAsString = handlebarsContext.Handlebars.Compile(text);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = templateBodyAsString(template),
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/WireMock.Net/Transformers/WireMockHandlebarsHelpers.cs
Normal file
30
src/WireMock.Net/Transformers/WireMockHandlebarsHelpers.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using HandlebarsDotNet;
|
||||
using HandlebarsDotNet.Helpers;
|
||||
using WireMock.Handlers;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class WireMockHandlebarsHelpers
|
||||
{
|
||||
public static void Register(IHandlebars handlebarsContext, IFileSystemHandler fileSystemHandler)
|
||||
{
|
||||
// Register https://github.com/StefH/Handlebars.Net.Helpers
|
||||
HandlebarsHelpers.Register(handlebarsContext);
|
||||
|
||||
// Register WireMock.Net specific helpers
|
||||
HandlebarsRegex.Register(handlebarsContext);
|
||||
|
||||
HandlebarsJsonPath.Register(handlebarsContext);
|
||||
|
||||
HandlebarsLinq.Register(handlebarsContext);
|
||||
|
||||
HandlebarsRandom.Register(handlebarsContext);
|
||||
|
||||
HandlebarsXeger.Register(handlebarsContext);
|
||||
|
||||
HandlebarsXPath.Register(handlebarsContext);
|
||||
|
||||
HandlebarsFile.Register(handlebarsContext, fileSystemHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,5 +52,10 @@ namespace WireMock.Util
|
||||
/// The detected body type (detection based on Content-Type).
|
||||
/// </summary>
|
||||
public BodyType DetectedBodyTypeFromContentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected compression.
|
||||
/// </summary>
|
||||
public string DetectedCompression { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
using WireMock.Validation;
|
||||
@@ -30,15 +30,15 @@ namespace WireMock.Util
|
||||
*/
|
||||
private static readonly IDictionary<string, bool> BodyAllowedForMethods = new Dictionary<string, bool>
|
||||
{
|
||||
{ "HEAD", false },
|
||||
{ "GET", false },
|
||||
{ "PUT", true },
|
||||
{ "POST", true },
|
||||
{ "DELETE", true },
|
||||
{ "TRACE", false },
|
||||
{ "OPTIONS", true },
|
||||
{ "CONNECT", false },
|
||||
{ "PATCH", true }
|
||||
{ HttpRequestMethods.HEAD, false },
|
||||
{ HttpRequestMethods.GET, false },
|
||||
{ HttpRequestMethods.PUT, true },
|
||||
{ HttpRequestMethods.POST, true },
|
||||
{ HttpRequestMethods.DELETE, true },
|
||||
{ HttpRequestMethods.TRACE, false },
|
||||
{ HttpRequestMethods.OPTIONS, true },
|
||||
{ HttpRequestMethods.CONNECT, false },
|
||||
{ HttpRequestMethods.PATCH, true }
|
||||
};
|
||||
|
||||
private static readonly IStringMatcher[] MultipartContentTypesMatchers = {
|
||||
@@ -107,15 +107,17 @@ namespace WireMock.Util
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType)
|
||||
public static async Task<BodyData> Parse([NotNull] BodyParserSettings settings)
|
||||
{
|
||||
Check.NotNull(stream, nameof(stream));
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
|
||||
var bodyWithContentEncoding = await ReadBytesAsync(settings.Stream, settings.ContentEncoding, settings.DecompressGZipAndDeflate);
|
||||
var data = new BodyData
|
||||
{
|
||||
BodyAsBytes = await ReadBytesAsync(stream),
|
||||
BodyAsBytes = bodyWithContentEncoding.Value,
|
||||
DetectedCompression = bodyWithContentEncoding.Key,
|
||||
DetectedBodyType = BodyType.Bytes,
|
||||
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(contentType)
|
||||
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(settings.ContentType)
|
||||
};
|
||||
|
||||
// In case of MultiPart: check if the BodyAsBytes is a valid UTF8 or ASCII string, in that case read as String else keep as-is
|
||||
@@ -127,8 +129,6 @@ namespace WireMock.Util
|
||||
data.BodyAsString = encoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = encoding;
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -142,7 +142,7 @@ namespace WireMock.Util
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
// If string is not null or empty, try to deserialize the string to a JObject
|
||||
if (!string.IsNullOrEmpty(data.BodyAsString))
|
||||
if (settings.DeserializeJson && !string.IsNullOrEmpty(data.BodyAsString))
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -162,12 +162,21 @@ namespace WireMock.Util
|
||||
|
||||
return data;
|
||||
}
|
||||
private static async Task<byte[]> ReadBytesAsync(Stream stream)
|
||||
|
||||
private static async Task<KeyValuePair<string, byte[]>> ReadBytesAsync(Stream stream, string contentEncoding = null, bool decompressGZipAndDeflate = true)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await stream.CopyToAsync(memoryStream);
|
||||
return memoryStream.ToArray();
|
||||
byte[] data = memoryStream.ToArray();
|
||||
|
||||
string type = contentEncoding?.ToLowerInvariant();
|
||||
if (decompressGZipAndDeflate && (type == "gzip" || type == "deflate"))
|
||||
{
|
||||
return new KeyValuePair<string, byte[]>(type, CompressionUtils.Decompress(type, data));
|
||||
}
|
||||
|
||||
return new KeyValuePair<string, byte[]>(null, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
src/WireMock.Net/Util/BodyParserSettings.cs
Normal file
17
src/WireMock.Net/Util/BodyParserSettings.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System.IO;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
internal class BodyParserSettings
|
||||
{
|
||||
public Stream Stream { get; set; }
|
||||
|
||||
public string ContentType { get; set; }
|
||||
|
||||
public string ContentEncoding { get; set; }
|
||||
|
||||
public bool DecompressGZipAndDeflate { get; set; } = true;
|
||||
|
||||
public bool DeserializeJson { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using FastDeepCloner;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
internal static class CloneUtils
|
||||
{
|
||||
private static FastDeepClonerSettings settings = new FastDeepCloner.FastDeepClonerSettings()
|
||||
{
|
||||
FieldType = FastDeepCloner.FieldType.FieldInfo,
|
||||
OnCreateInstance = new FastDeepCloner.Extensions.CreateInstance((Type type) =>
|
||||
{
|
||||
#if !NETSTANDARD1_3
|
||||
return FormatterServices.GetUninitializedObject(type);
|
||||
#else
|
||||
|
||||
#endif
|
||||
})
|
||||
};
|
||||
|
||||
public static T DeepClone<T>(T objectToBeCloned) where T : class
|
||||
{
|
||||
//return CloneExtensionsEx.CloneFactory.GetClone(objectToBeCloned);
|
||||
// Expression.Lambda<Func<object>>(Expression.New(type)).Compile()
|
||||
return FastDeepCloner.DeepCloner.Clone(objectToBeCloned, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
src/WireMock.Net/Util/CompressionUtils.cs
Normal file
49
src/WireMock.Net/Util/CompressionUtils.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
internal static class CompressionUtils
|
||||
{
|
||||
public static byte[] Compress(string contentEncoding, byte[] data)
|
||||
{
|
||||
using (var compressedStream = new MemoryStream())
|
||||
using (var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Compress))
|
||||
{
|
||||
zipStream.Write(data, 0, data.Length);
|
||||
|
||||
#if !NETSTANDARD1_3
|
||||
zipStream.Close();
|
||||
#endif
|
||||
return compressedStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] Decompress(string contentEncoding, byte[] data)
|
||||
{
|
||||
using (var compressedStream = new MemoryStream(data))
|
||||
using (var zipStream = Create(contentEncoding, compressedStream, CompressionMode.Decompress))
|
||||
using (var resultStream = new MemoryStream())
|
||||
{
|
||||
zipStream.CopyTo(resultStream);
|
||||
return resultStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream Create(string contentEncoding, Stream stream, CompressionMode mode)
|
||||
{
|
||||
switch (contentEncoding)
|
||||
{
|
||||
case "gzip":
|
||||
return new GZipStream(stream, mode);
|
||||
|
||||
case "deflate":
|
||||
return new DeflateStream(stream, mode);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"ContentEncoding '{contentEncoding}' is not supported.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
public class IndexableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value associated with the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index"> The index of the value to get.</param>
|
||||
/// <returns>The value associated with the specified index.</returns>
|
||||
public TValue this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
// get the item for that index.
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
return Values.Cast<TValue>().ToArray()[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// http://johnculviner.com/achieving-named-lock-locker-functionality-in-c-4-0/
|
||||
/// </summary>
|
||||
internal class NamedReaderWriterLocker
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, ReaderWriterLockSlim> _lockDict = new ConcurrentDictionary<string, ReaderWriterLockSlim>();
|
||||
|
||||
public ReaderWriterLockSlim GetLock(string name)
|
||||
{
|
||||
return _lockDict.GetOrAdd(name, s => new ReaderWriterLockSlim());
|
||||
}
|
||||
|
||||
public TResult RunWithReadLock<TResult>(string name, Func<TResult> body)
|
||||
{
|
||||
var rwLock = GetLock(name);
|
||||
try
|
||||
{
|
||||
rwLock.EnterReadLock();
|
||||
return body();
|
||||
}
|
||||
finally
|
||||
{
|
||||
rwLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void RunWithReadLock(string name, Action body)
|
||||
{
|
||||
var rwLock = GetLock(name);
|
||||
try
|
||||
{
|
||||
rwLock.EnterReadLock();
|
||||
body();
|
||||
}
|
||||
finally
|
||||
{
|
||||
rwLock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public TResult RunWithWriteLock<TResult>(string name, Func<TResult> body)
|
||||
{
|
||||
var rwLock = GetLock(name);
|
||||
try
|
||||
{
|
||||
rwLock.EnterWriteLock();
|
||||
return body();
|
||||
}
|
||||
finally
|
||||
{
|
||||
rwLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void RunWithWriteLock(string name, Action body)
|
||||
{
|
||||
var rwLock = GetLock(name);
|
||||
try
|
||||
{
|
||||
rwLock.EnterWriteLock();
|
||||
body();
|
||||
}
|
||||
finally
|
||||
{
|
||||
rwLock.ExitWriteLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveLock(string name)
|
||||
{
|
||||
_lockDict.TryRemove(name, out _);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace WireMock.Validation
|
||||
internal static class Check
|
||||
{
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T Condition<T>([NoEnumeration] T value, [NotNull] Predicate<T> condition, [InvokerParameterName] [NotNull] string parameterName)
|
||||
public static T Condition<T>([NoEnumeration] T value, [ValidatedNotNull, NotNull] Predicate<T> condition, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
{
|
||||
NotNull(condition, nameof(condition));
|
||||
NotNull(value, nameof(value));
|
||||
@@ -32,7 +32,7 @@ namespace WireMock.Validation
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
{
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
@@ -45,7 +45,7 @@ namespace WireMock.Validation
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName, [NotNull] string propertyName)
|
||||
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName, [ValidatedNotNull, NotNull] string propertyName)
|
||||
{
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace WireMock.Validation
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static IList<T> NotNullOrEmpty<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
public static IList<T> NotNullOrEmpty<T>(IList<T> value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
{
|
||||
NotNull(value, parameterName);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace WireMock.Validation
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static string NotNullOrEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
public static string NotNullOrEmpty(string value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
{
|
||||
Exception e = null;
|
||||
if (ReferenceEquals(value, null))
|
||||
@@ -96,20 +96,20 @@ namespace WireMock.Validation
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string NullButNotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
if (!ReferenceEquals(value, null)
|
||||
&& (value.Length == 0))
|
||||
{
|
||||
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||
//public static string NullButNotEmpty(string value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
//{
|
||||
// if (!ReferenceEquals(value, null)
|
||||
// && (value.Length == 0))
|
||||
// {
|
||||
// NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
|
||||
}
|
||||
// throw new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));
|
||||
// }
|
||||
|
||||
return value;
|
||||
}
|
||||
// return value;
|
||||
//}
|
||||
|
||||
public static IList<T> HasNoNulls<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
public static IList<T> HasNoNulls<T>(IList<T> value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
where T : class
|
||||
{
|
||||
NotNull(value, parameterName);
|
||||
@@ -124,16 +124,16 @@ namespace WireMock.Validation
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Type ValidEntityType(Type value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
if (!value.GetTypeInfo().IsClass)
|
||||
{
|
||||
NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||
//public static Type ValidEntityType(Type value, [InvokerParameterName, ValidatedNotNull, NotNull] string parameterName)
|
||||
//{
|
||||
// if (!value.GetTypeInfo().IsClass)
|
||||
// {
|
||||
// NotNullOrEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(CoreStrings.InvalidEntityType(value, parameterName));
|
||||
}
|
||||
// throw new ArgumentException(CoreStrings.InvalidEntityType(value, parameterName));
|
||||
// }
|
||||
|
||||
return value;
|
||||
}
|
||||
// return value;
|
||||
//}
|
||||
}
|
||||
}
|
||||
11
src/WireMock.Net/Validation/ValidatedNotNullAttribute.cs
Normal file
11
src/WireMock.Net/Validation/ValidatedNotNullAttribute.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace WireMock.Validation
|
||||
{
|
||||
/// <summary>
|
||||
/// To fix 'xxx' is null on at least one execution path. See also https://rules.sonarsource.com/csharp/RSPEC-3900.
|
||||
/// </summary>
|
||||
internal class ValidatedNotNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -3,28 +3,17 @@
|
||||
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
|
||||
<AssemblyTitle>WireMock.Net</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<!--<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>-->
|
||||
<!--<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>-->
|
||||
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net</AssemblyName>
|
||||
<PackageId>WireMock.Net</PackageId>
|
||||
<PackageTags>tdd;mock;http;wiremock;test;server;unittest</PackageTags>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
|
||||
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
<!--<DebugType>full</DebugType>
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>-->
|
||||
<ProjectGuid>{D3804228-91F4-4502-9595-39584E5A01AD}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<!--<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<!--<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>-->
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
@@ -36,7 +25,8 @@
|
||||
<None Include="WireMock.Net-Logo.png" Pack="true" PackagePath="../../"/>
|
||||
</ItemGroup>-->
|
||||
|
||||
<!--https://github.com/aspnet/RoslynCodeDomProvider/issues/51-->
|
||||
<!-- https://github.com/aspnet/RoslynCodeDomProvider/issues/51 -->
|
||||
<!-- This is needed else we cannot build net452 in Azure DevOps Pipeline -->
|
||||
<Target Name="CheckIfShouldKillVBCSCompiler" />
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
@@ -48,7 +38,7 @@
|
||||
<CodeAnalysisRuleSet>WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0'">
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<DefineConstants>NETSTANDARD;USE_ASPNETCORE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -61,33 +51,21 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Util\CloneUtils.cs" />
|
||||
<Compile Remove="Util\IndexableDictionary.cs" />
|
||||
<Compile Remove="Util\NamedReaderWriterLocker.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<!--<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />-->
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2019.1.3" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
|
||||
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Debug - Sonar'">
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="7.8.0.7320">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
|
||||
<PackageReference Include="JmesPath.Net" Version="1.0.125" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="[1.9.0]" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'net451' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard1.3' ">
|
||||
@@ -140,6 +118,13 @@
|
||||
<PackageReference Include="CS-Script.Core" Version="1.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.1'">
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.4" />
|
||||
|
||||
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/448 -->
|
||||
<PackageReference Include="CS-Script.Core" Version="1.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace WireMock.Net.Tests
|
||||
var listOfTasks = new List<Task<HttpResponseMessage>>();
|
||||
for (var i = 0; i < expectedCount; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
Thread.Sleep(50);
|
||||
listOfTasks.Add(http.GetAsync($"{server.Urls[0]}{path}"));
|
||||
}
|
||||
var responses = await Task.WhenAll(listOfTasks);
|
||||
|
||||
@@ -70,11 +70,9 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, 200)]
|
||||
[InlineData(-1, 200)]
|
||||
[InlineData(10000, 200)]
|
||||
[InlineData(300, 300)]
|
||||
public async Task OwinResponseMapper_MapAsync_StatusCode(object code, int expected)
|
||||
[InlineData(500, 500)]
|
||||
public async Task OwinResponseMapper_MapAsync_Valid_StatusCode(object code, int expected)
|
||||
{
|
||||
// Arrange
|
||||
var responseMessage = new ResponseMessage
|
||||
@@ -89,8 +87,46 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
||||
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, 200)]
|
||||
[InlineData(-1, 200)]
|
||||
[InlineData(10000, 200)]
|
||||
[InlineData(300, 300)]
|
||||
public async Task OwinResponseMapper_MapAsync_Invalid_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True(object code, int expected)
|
||||
{
|
||||
// Arrange
|
||||
_optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true);
|
||||
var responseMessage = new ResponseMessage
|
||||
{
|
||||
StatusCode = code
|
||||
};
|
||||
|
||||
// Act
|
||||
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
||||
|
||||
// Assert
|
||||
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OwinResponseMapper_MapAsync_StatusCodeNull()
|
||||
public async Task OwinResponseMapper_MapAsync_Null_StatusCode_When_AllowOnlyDefinedHttpStatusCodeInResponseSet_Is_True()
|
||||
{
|
||||
// Arrange
|
||||
_optionsMock.SetupGet(o => o.AllowOnlyDefinedHttpStatusCodeInResponse).Returns(true);
|
||||
var responseMessage = new ResponseMessage
|
||||
{
|
||||
StatusCode = null
|
||||
};
|
||||
|
||||
// Act
|
||||
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
||||
|
||||
// Assert
|
||||
_responseMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OwinResponseMapper_MapAsync_StatusCode_Is_Null()
|
||||
{
|
||||
// Arrange
|
||||
var responseMessage = new ResponseMessage
|
||||
@@ -110,10 +146,9 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
||||
[InlineData(-1, -1)]
|
||||
[InlineData(10000, 10000)]
|
||||
[InlineData(300, 300)]
|
||||
public async Task OwinResponseMapper_MapAsync_StatusCode_WithAllowAll(object code, int expected)
|
||||
public async Task OwinResponseMapper_MapAsync_StatusCode_Is_NotInEnumRange(object code, int expected)
|
||||
{
|
||||
// Arrange
|
||||
_optionsMock.SetupGet(o => o.AllowAnyHttpStatusCodeInResponse).Returns(true);
|
||||
var responseMessage = new ResponseMessage
|
||||
{
|
||||
StatusCode = code
|
||||
@@ -126,23 +161,6 @@ namespace WireMock.Net.Tests.Owin.Mappers
|
||||
_responseMock.VerifySet(r => r.StatusCode = expected, Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OwinResponseMapper_MapAsync_StatusCode_WithAllowAll_Null()
|
||||
{
|
||||
// Arrange
|
||||
_optionsMock.SetupGet(o => o.AllowAnyHttpStatusCodeInResponse).Returns(true);
|
||||
var responseMessage = new ResponseMessage
|
||||
{
|
||||
StatusCode = null
|
||||
};
|
||||
|
||||
// Act
|
||||
await _sut.MapAsync(responseMessage, _responseMock.Object);
|
||||
|
||||
// Assert
|
||||
_responseMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OwinResponseMapper_MapAsync_NoBody()
|
||||
{
|
||||
|
||||
@@ -8,18 +8,54 @@ namespace WireMock.Net.Tests.RequestBuilders
|
||||
{
|
||||
public class RequestBuilderUsingMethodTests
|
||||
{
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingConnect()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingConnect();
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("CONNECT");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingOptions()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingOptions();
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("OPTIONS");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingPatch()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingPatch();
|
||||
|
||||
// Assert 1
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("PATCH");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingTrace()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().UsingTrace();
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
Check.That(matchers.Count).IsEqualTo(1);
|
||||
Check.That((matchers[0] as RequestMessageMethodMatcher).Methods).ContainsExactly("TRACE");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_UsingAnyMethod_ClearsAllOtherMatches()
|
||||
{
|
||||
|
||||
@@ -243,18 +243,36 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
// assign
|
||||
BodyData bodyData;
|
||||
if (body is byte[] b)
|
||||
bodyData = await BodyParser.Parse(new MemoryStream(b), null);
|
||||
{
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(b),
|
||||
ContentType = null,
|
||||
DeserializeJson = true
|
||||
};
|
||||
bodyData = await BodyParser.Parse(bodyParserSettings);
|
||||
}
|
||||
else if (body is string s)
|
||||
bodyData = await BodyParser.Parse(new MemoryStream(Encoding.UTF8.GetBytes(s)), null);
|
||||
{
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(Encoding.UTF8.GetBytes(s)),
|
||||
ContentType = null,
|
||||
DeserializeJson = true
|
||||
};
|
||||
bodyData = await BodyParser.Parse(bodyParserSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", bodyData);
|
||||
|
||||
// act
|
||||
var result = new RequestMatchResult();
|
||||
var score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
|
||||
// assert
|
||||
Check.That(score).IsEqualTo(shouldMatch ? 1d : 0d);
|
||||
}
|
||||
@@ -265,7 +283,7 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
{
|
||||
var json = "{'a':'b'}";
|
||||
var str = "HelloWorld";
|
||||
var bytes = new byte[] {0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00};
|
||||
var bytes = new byte[] { 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00 };
|
||||
|
||||
return new TheoryData<object, RequestMessageBodyMatcher, bool>
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using NFluent;
|
||||
using FluentAssertions;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
@@ -17,15 +17,49 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
public async Task Response_WithCallback()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create().WithCallback(req => new ResponseMessage { BodyData = new BodyData { DetectedBodyType = BodyType.String, BodyAsString = req.Path + "Bar" }, StatusCode = 302 });
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = request.Path + "Bar"
|
||||
},
|
||||
StatusCode = 302
|
||||
});
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("/fooBar");
|
||||
Check.That(responseMessage.StatusCode).IsEqualTo(302);
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_WithCallback_And_UseTransformer_Is_True()
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = "{{request.Path}}Bar"
|
||||
},
|
||||
StatusCode = 302
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Threading.Tasks;
|
||||
using NFluent;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsHelpersTests
|
||||
{
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_HandlebarsHelpers_String_Uppercase()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "abc", DetectedBodyType = BodyType.String };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{String.Uppercase request.body}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("ABC");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,386 +1,432 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
#if NET452
|
||||
using Microsoft.Owin;
|
||||
#else
|
||||
using Microsoft.AspNetCore.Http;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsTests
|
||||
{
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "whatever",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test {{request.url}} {{request.path}} {{request.method}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_UrlPath()
|
||||
{
|
||||
// Assign
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "POST", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{request.url}} {{request.absoluteurl}} {{request.path}} {{request.absolutepath}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("http://localhost/a/b http://localhost/wiremock/a/b /a/b /wiremock/a/b");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_PathSegments()
|
||||
{
|
||||
// Assign
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "POST", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{request.pathsegments.[0]}} {{request.absolutepathsegments.[0]}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Query()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_StatusCode()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithStatusCode("{{request.query.a}}")
|
||||
.WithBody("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals("400");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_StatusCodeIsNull()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals(null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Header()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Headers()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsObject()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "test {{request.path}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"a\": \"test 1\", \"b\": \"test 2\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_And_TransformContentFromBodyAsFile()
|
||||
{
|
||||
// Assign
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("<xml MyUniqueNumber=\"{{request.query.MyUniqueNumber}}\"></xml>");
|
||||
|
||||
_settings.FileSystemHandler = filesystemHandlerMock.Object;
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer(true)
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String);
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"MyUniqueNumber\": \"1\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsString = jsonString,
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
DetectedBodyTypeFromContentType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
|
||||
|
||||
string jsonPath = "\"$.MyUniqueNumber\"";
|
||||
var response = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ?
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsNormalString()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"name\": \"WireMock\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsHandlebarsString()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"name\": \"WireMock\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson("{{{request.bodyAsJson}}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
#if NET452
|
||||
using Microsoft.Owin;
|
||||
#else
|
||||
using Microsoft.AspNetCore.Http;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsTests
|
||||
{
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithNullBody_ShouldNotThrowException()
|
||||
{
|
||||
// Assign
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "whatever",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test {{request.url}} {{request.path}} {{request.method}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Get")]
|
||||
[InlineData("Post")]
|
||||
public async Task Response_ProvideResponse_Handlebars_UrlPath(string httpMethod)
|
||||
{
|
||||
// Assign
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, httpMethod, ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{request.url}} {{request.absoluteurl}} {{request.path}} {{request.absolutepath}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("http://localhost/a/b http://localhost/wiremock/a/b /a/b /wiremock/a/b");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_PathSegments()
|
||||
{
|
||||
// Assign
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "POST", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{request.pathsegments.[0]}} {{request.absolutepathsegments.[0]}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Query()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_StatusCode()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithStatusCode("{{request.query.a}}")
|
||||
.WithBody("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals("400");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_StatusCodeIsNull()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals(null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Header()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Headers()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "abc",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsObject()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "test {{request.path}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"a\": \"test 1\", \"b\": \"test 2\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_And_TransformContentFromBodyAsFile()
|
||||
{
|
||||
// Assign
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("<xml MyUniqueNumber=\"{{request.query.MyUniqueNumber}}\"></xml>");
|
||||
|
||||
_settings.FileSystemHandler = filesystemHandlerMock.Object;
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithTransformer(true)
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String);
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsFile_JsonPath()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"MyUniqueNumber\": \"1\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsString = jsonString,
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
DetectedBodyTypeFromContentType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
|
||||
|
||||
string jsonPath = "\"$.MyUniqueNumber\"";
|
||||
var response = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ?
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsNormalString()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"name\": \"WireMock\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\"");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsHandlebarsString()
|
||||
{
|
||||
// Assign
|
||||
string jsonString = "{ \"name\": \"WireMock\" }";
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
|
||||
DetectedBodyType = BodyType.Json,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson("{{{request.bodyAsJson}}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsString_KeepsEncoding()
|
||||
{
|
||||
// Assign
|
||||
const string text = "my-text";
|
||||
Encoding enc = Encoding.Unicode;
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsString = text,
|
||||
DetectedBodyType = BodyType.String,
|
||||
Encoding = enc
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{request.body}}", BodyDestinationFormat.SameAsSource, enc)
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be(text);
|
||||
responseMessage.BodyData.Encoding.Should().Be(enc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithProxyTests : IDisposable
|
||||
{
|
||||
private const string ClientIp = "::1";
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
private readonly WireMockServer _server;
|
||||
private readonly Guid _guid;
|
||||
@@ -27,21 +28,32 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
_server = WireMockServer.Start();
|
||||
_server.Given(Request.Create().UsingPost().WithPath($"/{_guid}"))
|
||||
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 42 }).WithHeader("Content-Type", "application/json"));
|
||||
_server.Given(Request.Create().UsingPost().WithPath($"/{_guid}/append"))
|
||||
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 10 }).WithHeader("Content-Type", "application/json"));
|
||||
_server.Given(Request.Create().UsingPost().WithPath($"/prepend/{_guid}"))
|
||||
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 11 }).WithHeader("Content-Type", "application/json"));
|
||||
_server.Given(Request.Create().UsingPost().WithPath($"/prepend/{_guid}/append"))
|
||||
.RespondWith(Response.Create().WithStatusCode(201).WithBodyAsJson(new { p = 12 }).WithHeader("Content-Type", "application/json"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_WithProxy()
|
||||
[Theory]
|
||||
[InlineData("", "", "{\"p\":42}")]
|
||||
[InlineData("", "/append", "{\"p\":10}")]
|
||||
[InlineData("/prepend", "", "{\"p\":11}")]
|
||||
[InlineData("/prepend", "/append", "{\"p\":12}")]
|
||||
public async Task Response_WithProxy(string prepend, string append, string expectedBody)
|
||||
{
|
||||
// Assign
|
||||
var headers = new Dictionary<string, string[]> { { "Content-Type", new[] { "application/xml" } } };
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "POST", "::1", new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}{prepend}/{_guid}{append}"), "POST", ClientIp, new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
|
||||
var response = Response.Create().WithProxy(_server.Urls[0]);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("{\"p\":42}");
|
||||
Check.That(request.ProxyUrl).IsNotNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo(expectedBody);
|
||||
Check.That(responseMessage.StatusCode).IsEqualTo(201);
|
||||
Check.That(responseMessage.Headers["Content-Type"].ToString()).IsEqualTo("application/json");
|
||||
}
|
||||
@@ -63,7 +75,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var response = Response.Create().WithProxy(settings);
|
||||
|
||||
// Act
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", "::1");
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", ClientIp);
|
||||
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<HttpRequestException>();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
using NFluent;
|
||||
using System;
|
||||
using NFluent;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
@@ -19,10 +22,15 @@ namespace WireMock.Net.Tests.Util
|
||||
public async Task BodyParser_Parse_ContentTypeJson(string contentType, string bodyAsJson, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson)),
|
||||
ContentType = contentType,
|
||||
DeserializeJson = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
var body = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
@@ -38,10 +46,15 @@ namespace WireMock.Net.Tests.Util
|
||||
public async Task BodyParser_Parse_ContentTypeString(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString)),
|
||||
ContentType = contentType,
|
||||
DeserializeJson = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
var body = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
@@ -52,16 +65,42 @@ namespace WireMock.Net.Tests.Util
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] {34, 97, 34}, BodyType.Json)]
|
||||
[InlineData(new byte[] {97}, BodyType.String)]
|
||||
[InlineData(new byte[] {0xFF, 0xD8, 0xFF, 0xE0}, BodyType.Bytes)]
|
||||
[InlineData(new byte[] { 34, 97, 34 }, BodyType.Json)]
|
||||
[InlineData(new byte[] { 97 }, BodyType.String)]
|
||||
[InlineData(new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_DetectedBodyType(byte[] content, BodyType detectedBodyType)
|
||||
{
|
||||
// arrange
|
||||
var memoryStream = new MemoryStream(content);
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(content),
|
||||
ContentType = null,
|
||||
DeserializeJson = true
|
||||
};
|
||||
|
||||
// act
|
||||
var body = await BodyParser.Parse(memoryStream, null);
|
||||
var body = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// assert
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 34, 97, 34 }, BodyType.String)]
|
||||
[InlineData(new byte[] { 97 }, BodyType.String)]
|
||||
[InlineData(new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 }, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_DetectedBodyTypeNoJsonParsing(byte[] content, BodyType detectedBodyType)
|
||||
{
|
||||
// arrange
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(content),
|
||||
ContentType = null,
|
||||
DeserializeJson = false
|
||||
};
|
||||
|
||||
// act
|
||||
var body = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// assert
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
@@ -92,10 +131,15 @@ Content-Type: text/html
|
||||
|
||||
-----------------------------9051914041544843365972754266--";
|
||||
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(Encoding.UTF8.GetBytes(body)),
|
||||
ContentType = contentType,
|
||||
DeserializeJson = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
var result = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
|
||||
@@ -111,11 +155,15 @@ Content-Type: text/html
|
||||
// Arrange
|
||||
string contentType = "multipart/form-data";
|
||||
string body = char.ConvertFromUtf32(0x1D161); //U+1D161 = MUSICAL SYMBOL SIXTEENTH NOTE
|
||||
|
||||
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(Encoding.UTF8.GetBytes(body)),
|
||||
ContentType = contentType,
|
||||
DeserializeJson = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
var result = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
|
||||
@@ -126,14 +174,19 @@ Content-Type: text/html
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "hello", BodyType.String, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_ContentTypeIsNull(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
[InlineData("hello", BodyType.String, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_ContentTypeIsNull(string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString)),
|
||||
ContentType = null,
|
||||
DeserializeJson = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
var body = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
@@ -143,6 +196,60 @@ Content-Type: text/html
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("gzip")]
|
||||
[InlineData("deflate")]
|
||||
public async Task BodyParser_Parse_ContentEncoding_GZip_And_DecompressGzipAndDeflate_Is_True_Should_Decompress(string compression)
|
||||
{
|
||||
// Arrange
|
||||
var bytes = Encoding.ASCII.GetBytes("0");
|
||||
var compressed = CompressionUtils.Compress(compression, bytes);
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(compressed),
|
||||
ContentType = "text/plain",
|
||||
DeserializeJson = false,
|
||||
ContentEncoding = compression.ToUpperInvariant(),
|
||||
DecompressGZipAndDeflate = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
result.DetectedBodyType.Should().Be(BodyType.String);
|
||||
result.DetectedBodyTypeFromContentType.Should().Be(BodyType.String);
|
||||
result.BodyAsBytes.Should().BeEquivalentTo(new byte[] { 48 });
|
||||
result.BodyAsJson.Should().BeNull();
|
||||
result.BodyAsString.Should().Be("0");
|
||||
result.DetectedCompression.Should().Be(compression);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("gzip")]
|
||||
[InlineData("deflate")]
|
||||
public async Task BodyParser_Parse_ContentEncoding_GZip_And_DecompressGzipAndDeflate_Is_False_Should_Not_Decompress(string compression)
|
||||
{
|
||||
// Arrange
|
||||
var bytes = Encoding.ASCII.GetBytes(Guid.NewGuid().ToString());
|
||||
var compressed = CompressionUtils.Compress(compression, bytes);
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = new MemoryStream(compressed),
|
||||
ContentType = "text/plain",
|
||||
DeserializeJson = false,
|
||||
ContentEncoding = compression.ToUpperInvariant(),
|
||||
DecompressGZipAndDeflate = false
|
||||
};
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(bodyParserSettings);
|
||||
|
||||
// Assert
|
||||
result.BodyAsBytes.Should().BeEquivalentTo(compressed);
|
||||
result.DetectedCompression.Should().BeNull();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("HEAD", false)]
|
||||
[InlineData("GET", false)]
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net452;netcoreapp2.1</TargetFrameworks>
|
||||
<!--<TargetFramework>netcoreapp2.1</TargetFramework>-->
|
||||
<!--<TargetFrameworks>net452;netcoreapp2.1</TargetFrameworks>-->
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<DebugType>full</DebugType>
|
||||
<AssemblyName>WireMock.Net.Tests</AssemblyName>
|
||||
<PackageId>WireMock.Net.Tests</PackageId>
|
||||
@@ -19,6 +19,10 @@
|
||||
<AssemblyOriginatorKeyFile>../../src/WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
<!--<DelaySign>true</DelaySign>-->
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
|
||||
<!--https://developercommunity.visualstudio.com/content/problem/26347/unit-tests-fail-with-fileloadexception-newtonsoftj-1.html-->
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
@@ -31,21 +35,21 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Codecov" Version="1.1.0" />
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.3.1">
|
||||
<PackageReference Include="Codecov" Version="1.10.0" />
|
||||
<PackageReference Include="coverlet.msbuild" Version="2.8.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="FluentAssertions" Version="5.7.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="RestEase" Version="1.4.10" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.10" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||
<PackageReference Include="Moq" Version="4.10.1" />
|
||||
<PackageReference Include="Moq" Version="4.13.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="NFluent" Version="2.5.0" />
|
||||
<PackageReference Include="OpenCover" Version="4.6.519" />
|
||||
<PackageReference Include="ReportGenerator" Version="3.1.2" />
|
||||
<PackageReference Include="NFluent" Version="2.7.0" />
|
||||
<PackageReference Include="OpenCover" Version="4.7.922" />
|
||||
<PackageReference Include="ReportGenerator" Version="4.5.4" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
@@ -58,6 +62,7 @@
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net452'">
|
||||
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="3.1.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
|
||||
|
||||
@@ -5,7 +5,10 @@ using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using NFluent;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
@@ -50,7 +53,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_proxy_responses()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
server
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -76,7 +79,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_request()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -123,7 +126,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_exclude_blacklisted_content_header_in_mapping()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -165,7 +168,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_exclude_blacklisted_cookies_in_mapping()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -214,7 +217,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_request_with_empty_content()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -246,7 +249,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_preserve_content_header_in_proxied_response()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -277,7 +280,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_change_absolute_location_header_in_proxied_response()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var settings = new WireMockServerSettings { AllowPartialMapping = false };
|
||||
|
||||
var serverForProxyForwarding = WireMockServer.Start(settings);
|
||||
@@ -310,7 +313,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_preserve_cookie_header_in_proxied_request()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -379,7 +382,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_set_BodyAsJson_in_proxied_response()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -410,7 +413,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_set_Body_in_multipart_proxied_response()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -440,7 +443,7 @@ namespace WireMock.Net.Tests
|
||||
public async Task WireMockServer_Proxy_Should_Not_overrule_AdminMappings()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/prx_{Guid.NewGuid().ToString()}";
|
||||
string path = $"/prx_{Guid.NewGuid()}";
|
||||
var serverForProxyForwarding = WireMockServer.Start();
|
||||
serverForProxyForwarding
|
||||
.Given(Request.Create().WithPath(path))
|
||||
@@ -482,5 +485,37 @@ namespace WireMock.Net.Tests
|
||||
string content2 = await response2.Content.ReadAsStringAsync();
|
||||
Check.That(content2).IsEqualTo("[]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Proxy_WhenTargetIsNotAvailable_Should_Return_CorrectResponse()
|
||||
{
|
||||
// Assign
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||
{
|
||||
Url = $"http://error{Guid.NewGuid()}:12345"
|
||||
}
|
||||
};
|
||||
var server = WireMockServer.Start(settings);
|
||||
|
||||
// Act
|
||||
var requestMessage = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri(server.Urls[0])
|
||||
};
|
||||
var httpClientHandler = new HttpClientHandler { AllowAutoRedirect = false };
|
||||
var result = await new HttpClient(httpClientHandler).SendAsync(requestMessage);
|
||||
|
||||
// Assert
|
||||
result.StatusCode.Should().Be(500);
|
||||
|
||||
var content = await result.Content.ReadAsStringAsync();
|
||||
content.Should().Contain("known"); // On Linux it's "Name or service not known". On Windows it's "No such host is known.".
|
||||
|
||||
server.LogEntries.Should().HaveCount(1);
|
||||
((StatusModel) server.LogEntries.First().ResponseMessage.BodyData.BodyAsJson).Status.Should().Contain("known");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,21 +141,21 @@ namespace WireMock.Net.Tests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockServer_WireMockServerSettings_AllowAnyHttpStatusCodeInResponse()
|
||||
public void WireMockServer_WireMockServerSettings_AllowOnlyDefinedHttpStatusCodeInResponse()
|
||||
{
|
||||
// Assign and Act
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
Logger = _loggerMock.Object,
|
||||
AllowAnyHttpStatusCodeInResponse = true
|
||||
AllowOnlyDefinedHttpStatusCodeInResponse = true
|
||||
});
|
||||
|
||||
// Assert
|
||||
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
|
||||
Check.That(options.AllowAnyHttpStatusCodeInResponse).Equals(true);
|
||||
Check.That(options.AllowOnlyDefinedHttpStatusCodeInResponse).Equals(true);
|
||||
|
||||
// Verify
|
||||
_loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowAnyHttpStatusCodeInResponse") && s.Contains("True"))));
|
||||
_loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowOnlyDefinedHttpStatusCodeInResponse") && s.Contains("True"))));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NFluent;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests
|
||||
@@ -252,5 +256,35 @@ namespace WireMock.Net.Tests
|
||||
Check.That(response.StatusCode).Equals(HttpStatusCode.Created);
|
||||
Check.That(await response.Content.ReadAsStringAsync()).Contains("Mapping added");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("gzip")]
|
||||
[InlineData("deflate")]
|
||||
public async Task WireMockServer_Should_SupportRequestGZipAndDeflate(string contentEncoding)
|
||||
{
|
||||
// Arrange
|
||||
const string body = "hello wiremock";
|
||||
byte[] compressed = CompressionUtils.Compress(contentEncoding, Encoding.UTF8.GetBytes(body));
|
||||
|
||||
var server = WireMockServer.Start();
|
||||
server.Given(
|
||||
Request.Create()
|
||||
.WithPath("/foo")
|
||||
.WithBody("hello wiremock")
|
||||
)
|
||||
.RespondWith(
|
||||
Response.Create().WithBody("OK")
|
||||
);
|
||||
|
||||
var content = new StreamContent(new MemoryStream(compressed));
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
|
||||
content.Headers.ContentEncoding.Add(contentEncoding);
|
||||
|
||||
// Act
|
||||
var response = await new HttpClient().PostAsync($"{server.Urls[0]}/foo", content);
|
||||
|
||||
// Assert
|
||||
Check.That(await response.Content.ReadAsStringAsync()).Contains("OK");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user