Compare commits

..

1 Commits

Author SHA1 Message Date
Stef Heyenrath
4bfb97b192 wip 2020-10-12 21:48:37 +02:00
94 changed files with 1373 additions and 3363 deletions

3
.gitignore vendored
View File

@@ -252,6 +252,3 @@ paket-files/
*.sln.iml *.sln.iml
./report/coverlet/ ./report/coverlet/
/test/WireMock.Net.Tests/coverage.opencover.xml
/test/WireMock.Net.Tests/coverage.netcoreapp3.1.opencover.xml
/test/WireMock.Net.Tests/coverage.net5.0.opencover.xml

View File

@@ -1,39 +1,3 @@
# 1.3.8 (03 December 2020)
- [#542](https://github.com/WireMock-Net/WireMock.Net/pull/542) - Create dotnet-wiremock tool [feature] contributed by [StefH](https://github.com/StefH)
- [#543](https://github.com/WireMock-Net/WireMock.Net/pull/543) - Add support for .NET 5 [feature] contributed by [StefH](https://github.com/StefH)
- [#544](https://github.com/WireMock-Net/WireMock.Net/pull/544) - Use Java 11 in Azure Pipelines (needed for SonarCloud) [feature] contributed by [StefH](https://github.com/StefH)
- [#545](https://github.com/WireMock-Net/WireMock.Net/pull/545) - Fix SonarCloud OpenCover (coverlet-coverage) [bug] contributed by [StefH](https://github.com/StefH)
- [#547](https://github.com/WireMock-Net/WireMock.Net/pull/547) - Fix Proxying with SSL and NetCoreApp3.1 [bug] contributed by [StefH](https://github.com/StefH)
- [#524](https://github.com/WireMock-Net/WireMock.Net/issues/524) - Proxying with SSL Not Working in .NET Core 3.1 [bug]
# 1.3.7 (17 November 2020)
- [#539](https://github.com/WireMock-Net/WireMock.Net/pull/539) - Support for partial JSON matching contributed by [gleb-osokin](https://github.com/gleb-osokin)
# 1.3.6 (10 November 2020)
- [#529](https://github.com/WireMock-Net/WireMock.Net/pull/529) - Add assertions for ClientIP, Url and ProxyUrl [feature] contributed by [akamud](https://github.com/akamud)
- [#535](https://github.com/WireMock-Net/WireMock.Net/pull/535) - WithCallback should use also use enum HttpStatusCode [bug] contributed by [StefH](https://github.com/StefH)
- [#537](https://github.com/WireMock-Net/WireMock.Net/pull/537) - Add Custom Certificate settings [feature] contributed by [StefH](https://github.com/StefH)
- [#533](https://github.com/WireMock-Net/WireMock.Net/issues/533) - Stubbed response with only callback returns unexpected status code. [bug]
- [#536](https://github.com/WireMock-Net/WireMock.Net/issues/536) - Overriding the default ssl certificate via file. [feature]
# 1.3.5 (04 November 2020)
- [#530](https://github.com/WireMock-Net/WireMock.Net/pull/530) - Fix dotnet-sonarscanner [bug] contributed by [StefH](https://github.com/StefH)
- [#531](https://github.com/WireMock-Net/WireMock.Net/pull/531) - Add WithCallback-Async [feature] contributed by [StefH](https://github.com/StefH)
# 1.3.4 (17 October 2020)
- [#522](https://github.com/WireMock-Net/WireMock.Net/pull/522) - Add ContinuousIntegrationBuild property [feature] contributed by [StefH](https://github.com/StefH)
- [#525](https://github.com/WireMock-Net/WireMock.Net/pull/525) - Handlebars.Net.Helpers Version="1.1.0" [feature] contributed by [StefH](https://github.com/StefH)
# 1.3.3 (15 October 2020)
- [#520](https://github.com/WireMock-Net/WireMock.Net/pull/520) - Make kestrel limits configurable contributed by [eduherminio](https://github.com/eduherminio)
- [#521](https://github.com/WireMock-Net/WireMock.Net/issues/521) - Make Kestrel limits configurable [feature]
# 1.3.2 (14 October 2020)
- [#505](https://github.com/WireMock-Net/WireMock.Net/pull/505) - Fix reading JsonMatcher-mapping with object as pattern [bug] contributed by [StefH](https://github.com/StefH)
- [#514](https://github.com/WireMock-Net/WireMock.Net/pull/514) - Update .NET Core 3.1 example contributed by [Crossbow78](https://github.com/Crossbow78)
- [#504](https://github.com/WireMock-Net/WireMock.Net/issues/504) - Loading mapping models with `JsonMatcher` is not working correctly [bug]
- [#513](https://github.com/WireMock-Net/WireMock.Net/issues/513) - Static mapping break from 1.2.17 to 1.2.18 and higher [bug]
# 1.3.1 (30 September 2020) # 1.3.1 (30 September 2020)
- [#509](https://github.com/WireMock-Net/WireMock.Net/pull/509) - Adding netcoreapp3.1 as a target framework [feature] contributed by [APIWT](https://github.com/APIWT) - [#509](https://github.com/WireMock-Net/WireMock.Net/pull/509) - Adding netcoreapp3.1 as a target framework [feature] contributed by [APIWT](https://github.com/APIWT)

View File

@@ -4,7 +4,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<VersionPrefix>1.3.8</VersionPrefix> <VersionPrefix>1.3.1</VersionPrefix>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes> <PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl> <PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl> <PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
@@ -14,10 +14,6 @@
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon> <ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>
<Choose> <Choose>
<!-- The environment variable `Prerelease` is set in the azure-pipelines.yml file. --> <!-- The environment variable `Prerelease` is set in the azure-pipelines.yml file. -->
<When Condition=" '$(Prerelease)' != '' "> <When Condition=" '$(Prerelease)' != '' ">

View File

@@ -1,3 +1,3 @@
https://github.com/StefH/GitHubReleaseNotes https://github.com/StefH/GitHubReleaseNotes
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.3.8 GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.3.1

View File

@@ -1,8 +1,6 @@
# WireMock.Net # WireMock.Net
A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) which mimics the functionality from the JAVA based [WireMock.org](http://WireMock.org). A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) which mimics the functionality from the JAVA based [WireMock.org](http://WireMock.org).
For more info, see also this WIKI page: [What is WireMock.Net](https://github.com/WireMock-Net/WireMock.Net/wiki/What-Is-WireMock.Net).
## Key Features ## Key Features
* HTTP response stubbing, matchable on URL/Path, headers, cookies and body content patterns * HTTP response stubbing, matchable on URL/Path, headers, cookies and body content patterns
* Library can be used in unit tests and integration tests * Library can be used in unit tests and integration tests
@@ -23,9 +21,9 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
| | | | | |
| ***Quality*** | &nbsp; | | ***Quality*** | &nbsp; |
| &nbsp;&nbsp;**Build Azure** | [![Build Status Azure](https://stef.visualstudio.com/WireMock.Net/_apis/build/status/WireMock.Net)](https://stef.visualstudio.com/WireMock.Net/_build/latest?definitionId=7) | | &nbsp;&nbsp;**Build Azure** | [![Build Status Azure](https://stef.visualstudio.com/WireMock.Net/_apis/build/status/WireMock.Net)](https://stef.visualstudio.com/WireMock.Net/_build/latest?definitionId=7) |
| &nbsp;&nbsp;**Quality** | [![Sonar Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=WireMock-Net_WireMock.Net&metric=alert_status)](https://sonarcloud.io/project/issues?id=WireMock-Net_WireMock.Net) [![CodeFactor](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net/badge)](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net) | | &nbsp;&nbsp;**Quality** | [![Sonar Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=alert_status)](https://sonarcloud.io/project/issues?id=wiremock) [![CodeFactor](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net/badge)](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net) |
| &nbsp;&nbsp;**Sonar Bugs** | [![Sonar Bugs](https://sonarcloud.io/api/project_badges/measure?project=WireMock-Net_WireMock.Net&metric=bugs)](https://sonarcloud.io/project/issues?id=WireMock-Net_WireMock.Net&resolved=false&types=BUG) [![Sonar Code Smells](https://sonarcloud.io/api/project_badges/measure?project=WireMock-Net_WireMock.Net&metric=code_smells)](https://sonarcloud.io/project/issues?id=WireMock-Net_WireMock.Net&resolved=false&types=CODE_SMELL) | | &nbsp;&nbsp;**Sonar Bugs** | [![Sonar Bugs](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=bugs)](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=BUG) [![Sonar Code Smells](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=code_smells)](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=CODE_SMELL) |
| &nbsp;&nbsp;**Coverage** | [![Sonar Coverage](https://sonarcloud.io/api/project_badges/measure?project=WireMock-Net_WireMock.Net&metric=coverage)](https://sonarcloud.io/component_measures?id=WireMock-Net_WireMock.Net&metric=coverage) [![codecov](https://codecov.io/gh/WireMock-Net/WireMock.Net/branch/master/graph/badge.svg)](https://codecov.io/gh/WireMock-Net/WireMock.Net)| | &nbsp;&nbsp;**Coverage** | [![Sonar Coverage](https://sonarcloud.io/api/project_badges/measure?project=wiremock&metric=coverage)](https://sonarcloud.io/component_measures?id=wiremock&metric=coverage) [![codecov](https://codecov.io/gh/WireMock-Net/WireMock.Net/branch/master/graph/badge.svg)](https://codecov.io/gh/WireMock-Net/WireMock.Net) [![Coverage Status](https://coveralls.io/repos/github/WireMock-Net/WireMock.Net/badge.svg?branch=master)](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master) |
### NuGet packages ### NuGet packages
@@ -59,13 +57,9 @@ WireMock.Net can be used in several ways:
You can use your favorite test framework and use WireMock within your tests, see You can use your favorite test framework and use WireMock within your tests, see
[Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests). [Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests).
### As a dotnet tool
It's simple to install WireMock.Net as (global) dotnet tool, see [Wiki : dotnet tool](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-dotnet-tool).
### As standalone process / console application ### As standalone process / console application
This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process). This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process).
### As a Windows Service ### As a Windows Service
You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service). You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service).

View File

@@ -30,7 +30,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
CHANGELOG.md = CHANGELOG.md CHANGELOG.md = CHANGELOG.md
Directory.Build.props = Directory.Build.props Directory.Build.props = Directory.Build.props
GitHubReleaseNotes.txt = GitHubReleaseNotes.txt GitHubReleaseNotes.txt = GitHubReleaseNotes.txt
nuget.config = nuget.config
README.md = README.md README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject
@@ -72,12 +71,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication.NETCore3", "examples\WireMock.Net.WebApplication.NETCore3\WireMock.Net.WebApplication.NETCore3.csproj", "{E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.WebApplication.NETCore3", "examples\WireMock.Net.WebApplication.NETCore3\WireMock.Net.WebApplication.NETCore3.csproj", "{E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NETCoreApp3WithCertificate", "examples\WireMock.Net.Console.NETCoreApp3WithCertificate\WireMock.Net.Console.NETCoreApp3WithCertificate.csproj", "{925E421A-1B3F-4202-B48F-734743573A4B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-WireMock", "src\dotnet-WireMock.Net\dotnet-WireMock.csproj", "{40BF24B5-12E6-4610-9489-138798632E28}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.NET5", "examples\WireMock.Net.Console.NET5\WireMock.Net.Console.NET5.csproj", "{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -180,18 +173,6 @@ Global
{E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}.Release|Any CPU.Build.0 = Release|Any CPU {E1C56967-3DC7-46CB-A1DF-B13167A0D9D4}.Release|Any CPU.Build.0 = Release|Any CPU
{925E421A-1B3F-4202-B48F-734743573A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{925E421A-1B3F-4202-B48F-734743573A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{925E421A-1B3F-4202-B48F-734743573A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{925E421A-1B3F-4202-B48F-734743573A4B}.Release|Any CPU.Build.0 = Release|Any CPU
{40BF24B5-12E6-4610-9489-138798632E28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40BF24B5-12E6-4610-9489-138798632E28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40BF24B5-12E6-4610-9489-138798632E28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40BF24B5-12E6-4610-9489-138798632E28}.Release|Any CPU.Build.0 = Release|Any CPU
{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -221,9 +202,6 @@ Global
{B6269AAC-170A-4346-8B9A-579DED3D9A95} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2} {B6269AAC-170A-4346-8B9A-579DED3D9A95} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{6F38CB3A-6DA1-408A-AECD-E434523C2838} = {985E0ADB-D4B4-473A-AA40-567E279B7946} {6F38CB3A-6DA1-408A-AECD-E434523C2838} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{E1C56967-3DC7-46CB-A1DF-B13167A0D9D4} = {985E0ADB-D4B4-473A-AA40-567E279B7946} {E1C56967-3DC7-46CB-A1DF-B13167A0D9D4} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{925E421A-1B3F-4202-B48F-734743573A4B} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
{40BF24B5-12E6-4610-9489-138798632E28} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458} SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}

View File

@@ -1,5 +1,5 @@
pool: pool:
vmImage: 'Ubuntu-latest' vmImage: 'Ubuntu 16.04'
variables: variables:
buildConfiguration: 'Release' buildConfiguration: 'Release'

View File

@@ -1,136 +1,91 @@
pool:
vmImage: 'windows-2019'
variables: variables:
Prerelease: 'ci' Prerelease: 'ci'
buildId: "1$(Build.BuildId)" buildId: "1$(Build.BuildId)"
buildProjects: '**/src/**/*.csproj' buildProjects: '**/src/**/*.csproj'
jobs: steps:
- job: Linux_Build_Test_SonarCloud # Print buildId
- script: |
echo "BuildId = $(buildId)"
displayName: 'Print buildId'
pool: # Install Tools (SonarScanner)
vmImage: 'Ubuntu-latest' - script: |
dotnet tool install --global dotnet-sonarscanner
displayName: Install Tools (SonarScanner)
steps: # Begin SonarScanner
- script: | # See also
echo "BuildId = $(buildId)" # - https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools, else you get this error: `Since you just installed the .NET Core SDK, you will need to reopen the Command Prompt window before running the tool you installed.`
displayName: 'Print buildId' # - https://github.com/dotnet/cli/issues/8368
# - https://github.com/Microsoft/vsts-tasks/issues/8291
#
- script: |
%USERPROFILE%\.dotnet\tools\dotnet-sonarscanner begin /k:"wiremock" /o:"stefh-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$(SONAR_TOKEN)" /v:"$(buildId)" /d:sonar.cs.opencover.reportsPaths="**\coverage.opencover.xml"
displayName: Begin SonarScanner
condition: and(succeeded(), eq(variables['RUN_SONAR'], 'yes'))
- task: PowerShell@2 # Build source, tests and run tests for net452 and netcoreapp3.1 (with coverage)
displayName: "Use JDK11 by default" - script: |
inputs: dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework net452
targetType: 'inline' dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --framework netcoreapp3.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
script: | displayName: 'Build source, tests and run tests for net452 and netcoreapp3.1 (with coverage)'
$jdkPath = $env:JAVA_HOME_11_X64
Write-Host "##vso[task.setvariable variable=JAVA_HOME]$jdkPath"
- script: | # End SonarScanner
dotnet dev-certs https --trust || true - script: |
displayName: 'dotnet dev-certs https' %USERPROFILE%\.dotnet\tools\dotnet-sonarscanner end /d:sonar.login="$(SONAR_TOKEN)"
displayName: End SonarScanner
condition: and(succeeded(), eq(variables['RUN_SONAR'], 'yes'))
- task: SonarCloudPrepare@1 - task: whitesource.ws-bolt.bolt.wss.WhiteSource Bolt@19
displayName: 'Prepare analysis on SonarCloud' displayName: 'WhiteSource Bolt'
inputs: condition: and(succeeded(), eq(variables['RUN_WHITESOURCE'], 'yes'))
SonarCloud: SonarCloud
organization: wiremock-net
projectKey: 'WireMock-Net_WireMock.Net'
projectName: 'WireMock.Net'
extraProperties: |
sonar.cs.opencover.reportsPaths=**/coverage.netcoreapp3.1.opencover.xml
- task: DotNetCoreCLI@2 # Upload coverage to codecov.io
displayName: 'Build Unit tests' - script: |
inputs: %USERPROFILE%\.nuget\packages\codecov\1.10.0\tools\codecov.exe -f "./test/WireMock.Net.Tests/coverage.opencover.xml" -t $(CODECOV_TOKEN)
command: 'build' displayName: Upload coverage to codecov.io
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj'
arguments: '--configuration Debug --framework netcoreapp3.1'
- task: DotNetCoreCLI@2 # https://github.com/microsoft/azure-pipelines-tasks/issues/12212
displayName: 'Execute Unit tests' - task: PublishTestResults@2
inputs: condition: and(succeeded(), eq(variables['PUBLISH_TESTRESULTS'], 'yes'))
command: 'test' inputs:
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' testRunner: VSTest
arguments: '--no-build --configuration Debug --framework netcoreapp3.1 --collect:"XPlat Code Coverage" --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover' testResultsFiles: '**/*.trx'
- task: SonarCloudAnalyze@1 # Based on https://whereslou.com/2018/09/versioning-and-publishing-nuget-packages-automatically-using-azure-devops-pipelines/
displayName: 'SonarCloud: Run Code Analysis' - task: DotNetCoreCLI@2
displayName: Build Release
inputs:
command: 'build'
arguments: /p:Configuration=Release # https://github.com/MicrosoftDocs/vsts-docs/issues/1976
projects: $(buildProjects)
- task: SonarCloudPublish@1 - task: DotNetCoreCLI@2
displayName: 'SonarCloud: Publish Quality Gate Result' displayName: Pack
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
inputs:
command: pack
configuration: 'Release'
packagesToPack: $(buildProjects)
nobuild: true
packDirectory: '$(Build.ArtifactStagingDirectory)/packages'
verbosityPack: 'normal'
- task: whitesource.ws-bolt.bolt.wss.WhiteSource Bolt@19 - task: PublishBuildArtifacts@1
displayName: 'WhiteSource Bolt' displayName: Publish Artifacts
condition: and(succeeded(), eq(variables['RUN_WHITESOURCE'], 'yes')) condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
- script: | # https://github.com/NuGet/Home/issues/8148
bash <(curl https://codecov.io/bash) -t $(CODECOV_TOKEN) -f ./test/WireMock.Net.Tests/coverage.netcoreapp3.1.opencover.xml - task: DotNetCoreCLI@2
displayName: 'codecov' displayName: Push to MyGet
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
- task: PublishTestResults@2 inputs:
condition: and(succeeded(), eq(variables['PUBLISH_TESTRESULTS'], 'yes')) command: custom
inputs: custom: nuget
testRunner: VSTest arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg -n true -s https://www.myget.org/F/wiremock-net/api/v3/index.json -k $(MyGetKey)
testResultsFiles: '**/*.trx'
- task: PublishBuildArtifacts@1
displayName: Publish coverage file
inputs:
PathtoPublish: '/home/vsts/work/1/s/test/WireMock.Net.Tests/coverage.netcoreapp3.1.opencover.xml'
- job: Windows_Build_Test
dependsOn: Linux_Build_Test_SonarCloud
pool:
vmImage: 'windows-2019'
steps:
- task: DotNetCoreCLI@2
displayName: 'Build Unit tests'
inputs:
command: 'build'
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj'
arguments: '--configuration Debug --framework netcoreapp3.1'
- task: DotNetCoreCLI@2
displayName: 'Execute Unit tests'
inputs:
command: 'test'
projects: './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj'
arguments: '--no-build --configuration Debug --framework netcoreapp3.1 --collect:"XPlat Code Coverage" --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover'
- job: Windows_Release_to_MyGet
dependsOn: Windows_Build_Test
pool:
vmImage: 'windows-2019'
steps:
- task: DotNetCoreCLI@2
displayName: Build Release
inputs:
command: 'build'
arguments: /p:Configuration=Release
projects: $(buildProjects)
- task: DotNetCoreCLI@2
displayName: Pack
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
inputs:
command: pack
configuration: 'Release'
packagesToPack: $(buildProjects)
nobuild: true
packDirectory: '$(Build.ArtifactStagingDirectory)/packages'
verbosityPack: 'normal'
- task: PublishBuildArtifacts@1
displayName: Publish Artifacts
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
- task: DotNetCoreCLI@2
displayName: Push to MyGet
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
inputs:
command: custom
custom: nuget
arguments: push $(Build.ArtifactStagingDirectory)\packages\*.nupkg -n true -s https://www.myget.org/F/wiremock-net/api/v3/index.json -k $(MyGetKey)

View File

@@ -1,55 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</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="1.1.0" />
<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>

View File

@@ -1 +0,0 @@
// C# Hello

View File

@@ -1,22 +0,0 @@
{
"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" ]
}
}
}

View File

@@ -1,29 +0,0 @@
{
"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>Thats an error.</ins>\n <p>The requested URL <code>/proxy-google-test-post</code> was not found on this server. <ins>Thats 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"
}
}
}

View File

@@ -1,19 +0,0 @@
{
"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"
}
}
}

View File

@@ -1,22 +0,0 @@
{
"Request": {
"Path": {
"Matchers": [
{
"Name": "WildcardMatcher",
"Pattern": "/bodyasfilexmltest",
"IgnoreCase": false
}
]
},
"Methods": [
"get"
]
},
"Response": {
"StatusCode": 200,
"Headers": {"Content-Type": "application/xml"},
"BodyAsFile": "MyXmlResponse.xml",
"UseTransformer": false
}
}

View File

@@ -1,3 +0,0 @@
<xml>
<hello>world</hello>
</xml>

View File

@@ -1,46 +0,0 @@
[
{
"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"
}
}
}
]

View File

@@ -28,7 +28,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="1.1.0" /> <PackageReference Include="Handlebars.Net.Helpers" Version="1.0.0" />
<PackageReference Include="log4net" Version="2.0.8" /> <PackageReference Include="log4net" Version="2.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<!--<PackageReference Include="Microsoft.CodeAnalysis.Scripting.Common" Version="3.4.0" />--> <!--<PackageReference Include="Microsoft.CodeAnalysis.Scripting.Common" Version="3.4.0" />-->

View File

@@ -1,36 +0,0 @@
using WireMock.Logging;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.Console.NETCoreApp3WithCertificate
{
class Program
{
static void Main(string[] args)
{
string url = "https://localhost:8433/";
var server = WireMockServer.Start(new WireMockServerSettings
{
Urls = new[] { url },
StartAdminInterface = true,
Logger = new WireMockConsoleLogger(),
CertificateSettings = new WireMockCertificateSettings
{
X509StoreName = "My",
X509StoreLocation = "CurrentUser",
X509StoreThumbprintOrSubjectName = "FE16586076A8B3F3E2F1466803A6C4C7CA35455B"
// X509CertificateFilePath = "example.pfx",
// X509CertificatePassword = "wiremock"
}
});
System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
System.Console.WriteLine("Press any key to stop the server");
System.Console.ReadKey();
server.Stop();
}
}
}

View File

@@ -1,18 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="example.pfx">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -1,28 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIEsDCCApigAwIBAgIQJbH6hSGKdoFI0B7qCIOK7jANBgkqhkiG9w0BAQUFADAU
MRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMjAxMDMwMjMwMDAwWhcNMzAxMTA2MjMw
MDAwWjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4IC
DwAwggIKAoICAQCl5fQSrRgT3Q6WoULR98Y+rrDWtTTgVpbLU04G0hLZ4yUeP7Wa
yuVbvx7zX8XT4lA8Hu5T/GG91U077JcSSEjnPBFsh4hE7FkRoSYIEW6BFG7D7eUG
dGHnDV8UkSRQ97LJPyjXuHVDJzNDJ9xQGMzOZ4n8vQ7SEKBw9hRG2ugkP5b2jVIN
e1E549tq2jnIVpKCZ4+prf64ZLsaokX7VHe+b/CW3GoAqUUaUjdTpAQ7LpypJuFz
415enOrKQe+UEBdqhGlgcC/O/Bw0uq4qVk+NNe5DEINVwoYs9XjNdzxuIkkAtcCt
avTEzhHf8zWYLb5Nt2DIOcRGVELvRhsBX4um5f7dOGzMbXzBfUdjkP2O4hi6crhm
Hba5bNkj4Zw2EHR9Xua3nadGCj22z0vpMKP2gXdFVnxFqQlaUWBLtwwN9p6tCQHl
kU7wypvOHUsMa2Ojg5eZP4RpYFvZG3kkc9zTZCSakgw2n0ampBbvxPP11/AYIXtz
HKu3CKcpjVQ+lE0DAU/Mm77QJ24TMbXmAydwCf1UCdFbDUZhdM9lspHvA0J9eiCv
LOE94BrpVKuZ6TrAW0LZjAmBnkqYQAewhTW7GSgARE+QQcwfyu03Ck7id3Zt4FeQ
sQDo0NNj7zQOy3Y1GK0ZYAVZv/GUeHMkxpClSWPoub/f5SJ4YzD5Il0cQQIDAQAB
MA0GCSqGSIb3DQEBBQUAA4ICAQBd91xfUepnWcKwmupie2h1CAAQZEunyW78i++t
evABfBu0TgV4s6Xe0umFv9V4r+O+rrF3ddSudbSOPBEb0Ooe+e3YGlNk1JrI1EEn
fhb0YI8bMfBNpl85yNqxgByra7JF2mG4qbAnjrCs/PZkXo/34N29SY6dyZ7mffR3
r/l01Rdm3ogRwGkiMUeKb3iGwLUy1T55svuI3Zc13N+NJT1s9NqpwWeK/jFK/WRN
5Hi9W3DmlGCYAwFPCyBaQagxpGuGIpNsU0hKp86W5EvJpBpmCihfwlydH8ZbkHJ9
jx2UDgTCaDzmaiKysiTP2HHDBsReL4tjakBksa9jkTfy5ajB53F3aUVs4jvTA46L
w8wcAJlRPBz5siBrv4CH/0lBMyNeYzuqmDY3ulF4IMKNb5Kk9Ye4Pt0474z50A4v
fSah+9iwI/mubaJ5tK522AtWtUoOIAswIwpDQyNeJPOggyzT2Y2OYZdGuFAoMYuq
ZD58k4Yo+vky9K88l8NuzNJJvtgTKtT+/9qfMucxFmnvwbKEEULP3sw1FUKkPtM4
f242FIV/XnOeloDmhGGeTB7aODB+gGCvgmOH92njjUEIv+SnYQkflQaRhhyNIACi
ZvWlP/96H+X4fUG5kVNBHY021ZWmurUDqVxWUaswg63+DfsZcYtt6wgxiAN4ssXG
wLnLPw==
-----END CERTIFICATE-----

View File

@@ -12,7 +12,6 @@ using WireMock.ResponseBuilders;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
using WireMock.Util; using WireMock.Util;
using System.Threading.Tasks;
namespace WireMock.Net.ConsoleApplication namespace WireMock.Net.ConsoleApplication
{ {
@@ -250,13 +249,6 @@ namespace WireMock.Net.ConsoleApplication
.WithProxy("http://www.google.com") .WithProxy("http://www.google.com")
); );
server
.Given(Request.Create().WithHeader("ProxyThisHttps", "true")
.UsingGet())
.RespondWith(Response.Create()
.WithProxy("https://www.google.com")
);
server server
.Given(Request.Create().WithPath("/bodyasbytes.png") .Given(Request.Create().WithPath("/bodyasbytes.png")
.UsingGet()) .UsingGet())
@@ -529,29 +521,9 @@ namespace WireMock.Net.ConsoleApplication
.WithBodyAsJson(new { Id = "5bdf076c-5654-4b3e-842c-7caf1fabf8c9" })); .WithBodyAsJson(new { Id = "5bdf076c-5654-4b3e-842c-7caf1fabf8c9" }));
server server
.Given(Request.Create().WithPath("/random200or505").UsingGet()) .Given(Request.Create().WithPath("/random200or505").UsingGet())
.RespondWith(Response.Create().WithCallback(request => .RespondWith(Response.Create().WithCallback(request => new ResponseMessage
{ {
int code = new Random().Next(1, 2) == 1 ? 505 : 200; StatusCode = new Random().Next(1, 100) == 1 ? 504 : 200
return new ResponseMessage
{
BodyData = new BodyData { BodyAsString = "random200or505:" + code, DetectedBodyType = Types.BodyType.String },
StatusCode = code
};
}));
server
.Given(Request.Create().WithPath("/random200or505async").UsingGet())
.RespondWith(Response.Create().WithCallback(async request =>
{
await Task.Delay(1);
int code = new Random().Next(1, 2) == 1 ? 505 : 200;
return new ResponseMessage
{
BodyData = new BodyData { BodyAsString = "random200or505async:" + code, DetectedBodyType = Types.BodyType.String },
StatusCode = code
};
})); }));
System.Console.WriteLine(JsonConvert.SerializeObject(server.MappingModels, Formatting.Indented)); System.Console.WriteLine(JsonConvert.SerializeObject(server.MappingModels, Formatting.Indented));

View File

@@ -6,8 +6,6 @@ using System.Threading;
using log4net; using log4net;
using log4net.Config; using log4net.Config;
using log4net.Repository; using log4net.Repository;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
@@ -25,21 +23,11 @@ namespace WireMock.Net.StandAlone.NETCoreApp
{ {
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config")); XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
if (!WireMockServerSettingsParser.TryParseArguments(args, out var settings, new WireMockLog4NetLogger())) var settings = WireMockServerSettingsParser.ParseArguments(args, new WireMockLog4NetLogger());
{
return;
}
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'"))); settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
_server = WireMockServer.Start(settings); _server = WireMockServer.Start(settings);
//_server
// .Given(Request.Create()
// .UsingAnyMethod())
// .RespondWith(Response.Create()
// .WithProxy("https://www.google.com"));
Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down"); Console.WriteLine($"{DateTime.UtcNow} Press Ctrl+C to shut down");
Console.CancelKeyPress += (s, e) => Console.CancelKeyPress += (s, e) =>

View File

@@ -2,7 +2,7 @@
"profiles": { "profiles": {
"WireMock.Net.StandAlone.NETCoreApp": { "WireMock.Net.StandAlone.NETCoreApp": {
"commandName": "Project", "commandName": "Project",
"commandLineArgs": "--Urls https://localhost:10080 --WireMockLogger WireMockConsoleLogger" "commandLineArgs": "--Port 9091 --WireMockLogger WireMockConsoleLogger"
} }
} }
} }

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp3.1</TargetFrameworks> <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon> <ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<StartupObject>WireMock.Net.StandAlone.NETCoreApp.Program</StartupObject> <StartupObject>WireMock.Net.StandAlone.NETCoreApp.Program</StartupObject>
</PropertyGroup> </PropertyGroup>

View File

@@ -0,0 +1 @@
dotnet run --framework netcoreapp1.1

View File

@@ -0,0 +1 @@
dotnet run --framework netcoreapp2.0

View File

@@ -0,0 +1 @@
dotnet run --framework netcoreapp2.1

View File

@@ -13,15 +13,13 @@ namespace WireMock.Net.StandAlone.Net452
{ {
XmlConfigurator.Configure(new FileInfo("log4net.config")); XmlConfigurator.Configure(new FileInfo("log4net.config"));
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings)) var settings = WireMockServerSettingsParser.ParseArguments(args);
{ settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
WireMockServer.Start(settings); WireMockServer.Start(settings);
Console.WriteLine("Press any key to stop the server"); Console.WriteLine("Press any key to stop the server");
Console.ReadKey(); Console.ReadKey();
}
} }
} }
} }

View File

@@ -9,15 +9,13 @@ namespace WireMock.Net.StandAlone.Net461
{ {
static void Main(string[] args) static void Main(string[] args)
{ {
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings)) var settings = WireMockServerSettingsParser.ParseArguments(args);
{ settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
settings.Logger.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
WireMockServer.Start(settings); WireMockServer.Start(settings);
Console.WriteLine("Press any key to stop the server"); Console.WriteLine("Press any key to stop the server");
Console.ReadKey(); Console.ReadKey();
}
} }
} }
} }

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://www.nuget.org/api/v2/" />
<add key="coverlet" value="https://f.feedz.io/marcorossignoli/coverletunofficial/nuget/index.json" />
</packageSources>
</configuration>

View File

@@ -51,11 +51,7 @@ namespace WireMock.Server
event NotifyCollectionChangedEventHandler LogEntriesChanged; event NotifyCollectionChangedEventHandler LogEntriesChanged;
/// <summary> /// <summary>
/// Adds a 'catch all mapping' /// Adds the catch all mapping.
///
/// - matches all Paths and any Methods
/// - priority is set to 1000
/// - responds with a 404 "No matching mapping found"
/// </summary> /// </summary>
void AddCatchAllMapping(); void AddCatchAllMapping();
@@ -66,9 +62,9 @@ namespace WireMock.Server
void AddGlobalProcessingDelay(TimeSpan delay); void AddGlobalProcessingDelay(TimeSpan delay);
/// <summary> /// <summary>
/// Allows the partial mapping. /// Set the partial mapping to allowed (if true, you can also provide 'enforceHttpMethod').
/// </summary> /// </summary>
void AllowPartialMapping(bool allow = true); void AllowPartialMapping(bool allow = true, bool enforceHttpMethod = false);
/// <summary> /// <summary>
/// Deletes a LogEntry. /// Deletes a LogEntry.
@@ -87,18 +83,13 @@ namespace WireMock.Server
//IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false); //IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false);
/// <summary> /// <summary>
/// Reads a static mapping file and adds or updates a single mapping. /// Reads a static mapping file and adds or updates the mapping.
///
/// Calling this method manually forces WireMock.Net to read and apply the specified static mapping file.
/// </summary> /// </summary>
/// <param name="path">The path to the static mapping file.</param> /// <param name="path">The path.</param>
bool ReadStaticMappingAndAddOrUpdate([NotNull] string path); bool ReadStaticMappingAndAddOrUpdate([NotNull] string path);
/// <summary> /// <summary>
/// Reads the static mappings from a folder. /// Reads the static mappings from a folder.
/// (This method is also used when WireMockServerSettings.ReadStaticMappings is set to true.
///
/// Calling this method manually forces WireMock.Net to read and apply all static mapping files in the specified folder.
/// </summary> /// </summary>
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param> /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
void ReadStaticMappings([CanBeNull] string folder = null); void ReadStaticMappings([CanBeNull] string folder = null);
@@ -166,16 +157,12 @@ namespace WireMock.Server
/// <summary> /// <summary>
/// Register the mappings (via <see cref="MappingModel"/>). /// Register the mappings (via <see cref="MappingModel"/>).
///
/// This can be used if you have 1 or more <see cref="MappingModel"/> defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
/// </summary> /// </summary>
/// <param name="mappings">The MappingModels</param> /// <param name="mappings">The MappingModels</param>
IWireMockServer WithMapping(params MappingModel[] mappings); IWireMockServer WithMapping(params MappingModel[] mappings);
/// <summary> /// <summary>
/// Register the mappings (via json string). /// Register the mappings (via json string).
///
/// This can be used if you the mappings as json string defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
/// </summary> /// </summary>
/// <param name="mappings">The mapping(s) as json string.</param> /// <param name="mappings">The mapping(s) as json string.</param>
IWireMockServer WithMapping(string mappings); IWireMockServer WithMapping(string mappings);

View File

@@ -21,7 +21,6 @@
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<!--<DelaySign>true</DelaySign>--> <!--<DelaySign>true</DelaySign>-->
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">

View File

@@ -16,7 +16,8 @@ namespace WireMock.FluentAssertions
} }
[CustomAssertion] [CustomAssertion]
public AndConstraint<WireMockAssertions> AtAbsoluteUrl(string absoluteUrl, string because = "", params object[] becauseArgs) public AndConstraint<WireMockAssertions> AtAbsoluteUrl(string absoluteUrl, string because = "",
params object[] becauseArgs)
{ {
Execute.Assertion Execute.Assertion
.BecauseOf(because, becauseArgs) .BecauseOf(because, becauseArgs)
@@ -35,11 +36,13 @@ namespace WireMock.FluentAssertions
} }
[CustomAssertion] [CustomAssertion]
public AndConstraint<WireMockAssertions> WithHeader(string expectedKey, string value, string because = "", params object[] becauseArgs) public AndConstraint<WireMockAssertions> WithHeader(string expectedKey, string value,
string because = "", params object[] becauseArgs)
=> WithHeader(expectedKey, new[] {value}, because, becauseArgs); => WithHeader(expectedKey, new[] {value}, because, becauseArgs);
[CustomAssertion] [CustomAssertion]
public AndConstraint<WireMockAssertions> WithHeader(string expectedKey, string[] expectedValues, string because = "", params object[] becauseArgs) public AndConstraint<WireMockAssertions> WithHeader(string expectedKey, string[] expectedValues,
string because = "", params object[] becauseArgs)
{ {
var headersDictionary = _subject.LogEntries.SelectMany(x => x.RequestMessage.Headers) var headersDictionary = _subject.LogEntries.SelectMany(x => x.RequestMessage.Headers)
.ToDictionary(x => x.Key, x => x.Value); .ToDictionary(x => x.Key, x => x.Value);
@@ -69,62 +72,5 @@ namespace WireMock.FluentAssertions
return new AndConstraint<WireMockAssertions>(this); return new AndConstraint<WireMockAssertions>(this);
} }
[CustomAssertion]
public AndConstraint<WireMockAssertions> AtUrl(string url, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => _subject.LogEntries.Select(x => x.RequestMessage).ToList())
.ForCondition(requests => requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the url {0}{reason}, but no calls were made.",
url)
.Then
.ForCondition(x => x.Any(y => y.Url == url))
.FailWith(
"Expected {context:wiremockserver} to have been called at address matching the url {0}{reason}, but didn't find it among the calls to {1}.",
_ => url, requests => requests.Select(request => request.Url));
return new AndConstraint<WireMockAssertions>(this);
}
[CustomAssertion]
public AndConstraint<WireMockAssertions> WithProxyUrl(string proxyUrl, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => _subject.LogEntries.Select(x => x.RequestMessage).ToList())
.ForCondition(requests => requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called with proxy url {0}{reason}, but no calls were made.",
proxyUrl)
.Then
.ForCondition(x => x.Any(y => y.ProxyUrl == proxyUrl))
.FailWith(
"Expected {context:wiremockserver} to have been called with proxy url {0}{reason}, but didn't find it among the calls with {1}.",
_ => proxyUrl, requests => requests.Select(request => request.ProxyUrl));
return new AndConstraint<WireMockAssertions>(this);
}
[CustomAssertion]
public AndConstraint<WireMockAssertions> FromClientIP(string clientIP, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.Given(() => _subject.LogEntries.Select(x => x.RequestMessage).ToList())
.ForCondition(requests => requests.Any())
.FailWith(
"Expected {context:wiremockserver} to have been called from client IP {0}{reason}, but no calls were made.",
clientIP)
.Then
.ForCondition(x => x.Any(y => y.ClientIP == clientIP))
.FailWith(
"Expected {context:wiremockserver} to have been called from client IP {0}{reason}, but didn't find it among the calls from IP(s) {1}.",
_ => clientIP, requests => requests.Select(request => request.ClientIP));
return new AndConstraint<WireMockAssertions>(this);
}
} }
} }

View File

@@ -21,7 +21,6 @@
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<!--<DelaySign>true</DelaySign>--> <!--<DelaySign>true</DelaySign>-->
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">

View File

@@ -11,7 +11,6 @@
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> <PropertyGroup Condition="'$(Configuration)' == 'Release'">

View File

@@ -21,7 +21,6 @@
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
<!--<DelaySign>true</DelaySign>--> <!--<DelaySign>true</DelaySign>-->
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign> <PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">

View File

@@ -1,5 +1,5 @@
using System.Linq; using JetBrains.Annotations;
using JetBrains.Annotations; using System.Linq;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
@@ -38,37 +38,11 @@ namespace WireMock.Net.StandAlone
{ {
Check.NotNull(args, nameof(args)); Check.NotNull(args, nameof(args));
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings, logger)) var settings = WireMockServerSettingsParser.ParseArguments(args, logger);
{
settings.Logger?.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
return Start(settings); settings.Logger?.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
}
return null; return Start(settings);
}
/// <summary>
/// Try to start WireMock.Net standalone Server based on the commandline arguments.
/// </summary>
/// <param name="args">The commandline arguments</param>
/// <param name="logger">The logger</param>
/// <param name="server">The WireMockServer</param>
[PublicAPI]
public static bool TryStart([NotNull] string[] args, out WireMockServer server, [CanBeNull] IWireMockLogger logger = null)
{
Check.NotNull(args, nameof(args));
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings, logger))
{
settings.Logger?.Debug("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
server = Start(settings);
return true;
}
server = null;
return false;
} }
} }
} }

View File

@@ -3,7 +3,7 @@
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description> <Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle> <AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Authors>Stef Heyenrath</Authors> <Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0</TargetFrameworks> <TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.StandAlone</AssemblyName> <AssemblyName>WireMock.Net.StandAlone</AssemblyName>
<PackageId>WireMock.Net.StandAlone</PackageId> <PackageId>WireMock.Net.StandAlone</PackageId>

View File

@@ -13,7 +13,7 @@ namespace WireMock.Http
{ {
public static HttpClient CreateHttpClient(IProxyAndRecordSettings settings) public static HttpClient CreateHttpClient(IProxyAndRecordSettings settings)
{ {
#if NETSTANDARD || NETCOREAPP3_1 || NET5_0 #if NETSTANDARD || NETCOREAPP3_1
var handler = new HttpClientHandler var handler = new HttpClientHandler
{ {
CheckCertificateRevocationList = false, CheckCertificateRevocationList = false,
@@ -27,19 +27,21 @@ namespace WireMock.Http
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true, ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
}; };
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
#else #else
var handler = new WebRequestHandler var handler = new WebRequestHandler
{ {
ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true, ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
}; };
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;
#endif #endif
if (!string.IsNullOrEmpty(settings.ClientX509Certificate2ThumbprintOrSubjectName)) if (!string.IsNullOrEmpty(settings.ClientX509Certificate2ThumbprintOrSubjectName))
{ {
handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ClientCertificateOptions = ClientCertificateOption.Manual;
var x509Certificate2 = CertificateLoader.LoadCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName); var x509Certificate2 = ClientCertificateHelper.GetCertificate(settings.ClientX509Certificate2ThumbprintOrSubjectName);
handler.ClientCertificates.Add(x509Certificate2); handler.ClientCertificates.Add(x509Certificate2);
} }
@@ -59,12 +61,11 @@ namespace WireMock.Http
} }
} }
#if !NETSTANDARD1_3 var client = new HttpClient(handler);
#if NET452 || NET46
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ServicePointManager.ServerCertificateValidationCallback = (message, cert, chain, errors) => true;
#endif #endif
return client;
return new HttpClient(handler);
} }
public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson, bool decompressGzipAndDeflate) public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage requestMessage, string url, bool deserializeJson, bool decompressGzipAndDeflate)

View File

@@ -59,29 +59,15 @@ namespace WireMock.Http
foreach (var header in requestMessage.Headers.Where(h => !excludeHeaders.Contains(h.Key, StringComparer.OrdinalIgnoreCase))) foreach (var header in requestMessage.Headers.Where(h => !excludeHeaders.Contains(h.Key, StringComparer.OrdinalIgnoreCase)))
{ {
// Skip if already added. We need to ToList() else calling httpRequestMessage.Headers.Contains() with a header starting with a ":" throws an exception. // Try to add to request headers. If failed - try to add to content headers
if (httpRequestMessage.Headers.ToList().Any(h => string.Equals(h.Key, header.Key, StringComparison.OrdinalIgnoreCase))) if (httpRequestMessage.Headers.Contains(header.Key))
{ {
continue; continue;
} }
// Skip if already added. We need to ToList() else calling httpRequestMessage.Content.Headers.Contains(...) with a header starting with a ":" throws an exception. if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))
if (httpRequestMessage.Content != null && httpRequestMessage.Content.Headers.ToList().Any(h => string.Equals(h.Key, header.Key, StringComparison.OrdinalIgnoreCase)))
{ {
continue; httpRequestMessage.Content.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
// Try to add to request headers. If failed - try to add to content headers. If still fails, just ignore this header.
try
{
if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))
{
httpRequestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
}
catch
{
// Just continue
} }
} }

View File

@@ -1,100 +0,0 @@
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace WireMock.HttpsCertificate
{
internal static class CertificateLoader
{
/// <summary>
/// Used by the WireMock.Net server
/// </summary>
public static X509Certificate2 LoadCertificate(
string storeName,
string storeLocation,
string thumbprintOrSubjectName,
string filePath,
string password,
string host)
{
if (!string.IsNullOrEmpty(storeName) && !string.IsNullOrEmpty(storeLocation))
{
var thumbprintOrSubjectNameOrHost = thumbprintOrSubjectName ?? host;
var certStore = new X509Store((StoreName)Enum.Parse(typeof(StoreName), storeName), (StoreLocation)Enum.Parse(typeof(StoreLocation), storeLocation));
try
{
certStore.Open(OpenFlags.ReadOnly);
// Attempt to find by Thumbprint first
var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjectNameOrHost, false);
if (matchingCertificates.Count == 0)
{
// Fallback to SubjectName
matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubjectNameOrHost, false);
if (matchingCertificates.Count == 0)
{
// No certificates matched the search criteria.
throw new FileNotFoundException($"No Certificate found with in store '{storeName}', location '{storeLocation}' for Thumbprint or SubjectName '{thumbprintOrSubjectNameOrHost}'.");
}
}
// Use the first matching certificate.
return matchingCertificates[0];
}
finally
{
#if NETSTANDARD || NET46
certStore.Dispose();
#else
certStore.Close();
#endif
}
}
if (!string.IsNullOrEmpty(filePath) && !string.IsNullOrEmpty(password))
{
return new X509Certificate2(filePath, password);
}
throw new InvalidOperationException("X509StoreName and X509StoreLocation OR X509CertificateFilePath and X509CertificatePassword are mandatory.");
}
/// <summary>
/// Used for Proxy
/// </summary>
public static X509Certificate2 LoadCertificate(string thumbprintOrSubjectName)
{
var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
try
{
// Certificate must be in the local machine store
certStore.Open(OpenFlags.ReadOnly);
// Attempt to find by Thumbprint first
var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjectName, false);
if (matchingCertificates.Count == 0)
{
// Fallback to SubjectName
matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubjectName, false);
if (matchingCertificates.Count == 0)
{
// No certificates matched the search criteria.
throw new FileNotFoundException("No certificate found with specified Thumbprint or SubjectName.", thumbprintOrSubjectName);
}
}
// Use the first matching certificate.
return matchingCertificates[0];
}
finally
{
#if NETSTANDARD || NET46
certStore.Dispose();
#else
certStore.Close();
#endif
}
}
}
}

View File

@@ -0,0 +1,42 @@
using System.IO;
using System.Security.Cryptography.X509Certificates;
namespace WireMock.HttpsCertificate
{
internal static class ClientCertificateHelper
{
public static X509Certificate2 GetCertificate(string thumbprintOrSubjectName)
{
X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
try
{
// Certificate must be in the local machine store
certStore.Open(OpenFlags.ReadOnly);
// Attempt to find by thumbprint first
var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjectName, false);
if (matchingCertificates.Count == 0)
{
// Fallback to subject name
matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubjectName, false);
if (matchingCertificates.Count == 0)
{
// No certificates matched the search criteria.
throw new FileNotFoundException("No certificate found with specified Thumbprint or SubjectName.", thumbprintOrSubjectName);
}
}
// Use the first matching certificate.
return matchingCertificates[0];
}
finally
{
#if NETSTANDARD || NET46
certStore.Dispose();
#else
certStore.Close();
#endif
}
}
}
}

View File

@@ -151,7 +151,7 @@ namespace WireMock.Matchers
throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex); throw new WireMockException("CSharpCodeMatcher: Problem calling method 'IsMatch' in WireMock.CodeHelper", ex);
} }
#elif (NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1 || NET5_0) #elif (NETSTANDARD2_0 || NETSTANDARD2_1 || NETCOREAPP3_1)
dynamic script; dynamic script;
try try
{ {

View File

@@ -1,5 +1,4 @@
using System; using System.Collections;
using System.Collections;
using System.Linq; using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -18,7 +17,7 @@ namespace WireMock.Matchers
public object Value { get; } public object Value { get; }
/// <inheritdoc cref="IMatcher.Name"/> /// <inheritdoc cref="IMatcher.Name"/>
public virtual string Name => "JsonMatcher"; public string Name => "JsonMatcher";
/// <inheritdoc cref="IMatcher.MatchBehaviour"/> /// <inheritdoc cref="IMatcher.MatchBehaviour"/>
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
@@ -30,7 +29,6 @@ namespace WireMock.Matchers
public bool ThrowException { get; } public bool ThrowException { get; }
private readonly JToken _valueAsJToken; private readonly JToken _valueAsJToken;
private readonly Func<JToken, JToken> _jTokenConverter;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JsonMatcher"/> class. /// Initializes a new instance of the <see cref="JsonMatcher"/> class.
@@ -69,9 +67,6 @@ namespace WireMock.Matchers
Value = value; Value = value;
_valueAsJToken = ConvertValueToJToken(value); _valueAsJToken = ConvertValueToJToken(value);
_jTokenConverter = ignoreCase
? (Func<JToken, JToken>)Rename
: jToken => jToken;
} }
/// <inheritdoc cref="IObjectMatcher.IsMatch"/> /// <inheritdoc cref="IObjectMatcher.IsMatch"/>
@@ -86,9 +81,7 @@ namespace WireMock.Matchers
{ {
var inputAsJToken = ConvertValueToJToken(input); var inputAsJToken = ConvertValueToJToken(input);
match = IsMatch( match = DeepEquals(_valueAsJToken, inputAsJToken);
_jTokenConverter(_valueAsJToken),
_jTokenConverter(inputAsJToken));
} }
catch (JsonException) catch (JsonException)
{ {
@@ -102,17 +95,6 @@ namespace WireMock.Matchers
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match)); return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(match));
} }
/// <summary>
/// Compares the input against the matcher value
/// </summary>
/// <param name="value">Matcher value</param>
/// <param name="input">Input value</param>
/// <returns></returns>
protected virtual bool IsMatch(JToken value, JToken input)
{
return JToken.DeepEquals(value, input);
}
private static JToken ConvertValueToJToken(object value) private static JToken ConvertValueToJToken(object value)
{ {
// Check if JToken, string, IEnumerable or object // Check if JToken, string, IEnumerable or object
@@ -132,6 +114,19 @@ namespace WireMock.Matchers
} }
} }
private bool DeepEquals(JToken value, JToken input)
{
if (!IgnoreCase)
{
return JToken.DeepEquals(value, input);
}
JToken renamedValue = Rename(value);
JToken renamedInput = Rename(input);
return JToken.DeepEquals(renamedValue, renamedInput);
}
private static string ToUpper(string input) private static string ToUpper(string input)
{ {
return input?.ToUpperInvariant(); return input?.ToUpperInvariant();

View File

@@ -1,87 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json.Linq;
namespace WireMock.Matchers
{
/// <summary>
/// JsonPartialMatcher
/// </summary>
public class JsonPartialMatcher : JsonMatcher
{
/// <inheritdoc cref="IMatcher.Name"/>
public override string Name => "JsonPartialMatcher";
/// <summary>
/// Initializes a new instance of the <see cref="JsonPartialMatcher"/> class.
/// </summary>
/// <param name="value">The string value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonPartialMatcher([NotNull] string value, bool ignoreCase = false, bool throwException = false)
: base(value, ignoreCase, throwException)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonPartialMatcher"/> class.
/// </summary>
/// <param name="value">The object value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonPartialMatcher([NotNull] object value, bool ignoreCase = false, bool throwException = false)
: base(value, ignoreCase, throwException)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="JsonPartialMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="value">The value to check for equality.</param>
/// <param name="ignoreCase">Ignore the case from the PropertyName and PropertyValue (string only).</param>
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
public JsonPartialMatcher(MatchBehaviour matchBehaviour, [NotNull] object value, bool ignoreCase = false, bool throwException = false)
: base(matchBehaviour, value, ignoreCase, throwException)
{
}
/// <inheritdoc />
protected override bool IsMatch(JToken value, JToken input)
{
if (value == null || value == input)
{
return true;
}
if (input == null || value.Type != input.Type)
{
return false;
}
switch (value.Type)
{
case JTokenType.Object:
var nestedValues = value.ToObject<Dictionary<string, JToken>>();
return nestedValues?.Any() != true ||
nestedValues.All(pair => IsMatch(pair.Value, input.SelectToken(pair.Key)));
case JTokenType.Array:
var valuesArray = value.ToObject<JToken[]>();
var tokenArray = input.ToObject<JToken[]>();
if (valuesArray?.Any() != true)
{
return true;
}
return tokenArray?.Any() == true &&
valuesArray.All(subFilter => tokenArray.Any(subToken => IsMatch(subFilter, subToken)));
default:
return value.ToString() == input.ToString();
}
}
}
}

View File

@@ -1,10 +1,8 @@
#if USE_ASPNETCORE && !NETSTANDARD1_3 #if USE_ASPNETCORE && !NETSTANDARD1_3
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WireMock.HttpsCertificate;
namespace WireMock.Owin namespace WireMock.Owin
{ {
@@ -18,56 +16,23 @@ namespace WireMock.Owin
options.Limits.MaxResponseBufferSize = null; options.Limits.MaxResponseBufferSize = null;
} }
private static void SetHttpsAndUrls(KestrelServerOptions kestrelOptions, IWireMockMiddlewareOptions wireMockMiddlewareOptions, IEnumerable<HostUrlDetails> urlDetails) private static void SetHttpsAndUrls(KestrelServerOptions options, ICollection<(string Url, int Port)> urlDetails)
{ {
foreach (var urlDetail in urlDetails) foreach (var detail in urlDetails)
{ {
if (urlDetail.IsHttps) if (detail.Url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{ {
kestrelOptions.Listen(System.Net.IPAddress.Any, urlDetail.Port, listenOptions => options.Listen(System.Net.IPAddress.Any, detail.Port, listenOptions =>
{ {
if (wireMockMiddlewareOptions.CustomCertificateDefined) listenOptions.UseHttps();
{
listenOptions.UseHttps(CertificateLoader.LoadCertificate(
wireMockMiddlewareOptions.X509StoreName,
wireMockMiddlewareOptions.X509StoreLocation,
wireMockMiddlewareOptions.X509ThumbprintOrSubjectName,
wireMockMiddlewareOptions.X509CertificateFilePath,
wireMockMiddlewareOptions.X509CertificatePassword,
urlDetail.Host)
);
}
else
{
listenOptions.UseHttps();
}
}); });
} }
else else
{ {
kestrelOptions.Listen(System.Net.IPAddress.Any, urlDetail.Port); options.Listen(System.Net.IPAddress.Any, detail.Port);
} }
} }
} }
} }
internal static class IWebHostBuilderExtensions
{
internal static IWebHostBuilder ConfigureAppConfigurationUsingEnvironmentVariables(this IWebHostBuilder builder)
{
return builder.ConfigureAppConfiguration(config =>
{
config.AddEnvironmentVariables();
});
}
internal static IWebHostBuilder ConfigureKestrelServerOptions(this IWebHostBuilder builder)
{
return builder.ConfigureServices((context, services) =>
{
services.Configure<KestrelServerOptions>(context.Configuration.GetSection("Kestrel"));
});
}
}
} }
#endif #endif

View File

@@ -1,9 +1,9 @@
#if USE_ASPNETCORE && NETSTANDARD1_3 #if USE_ASPNETCORE && NETSTANDARD1_3
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.Kestrel; using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WireMock.HttpsCertificate; using WireMock.HttpsCertificate;
namespace WireMock.Owin namespace WireMock.Owin
@@ -17,47 +17,14 @@ namespace WireMock.Owin
options.Limits.MaxResponseBufferSize = null; options.Limits.MaxResponseBufferSize = null;
} }
private static void SetHttpsAndUrls(KestrelServerOptions options, IWireMockMiddlewareOptions wireMockMiddlewareOptions, IEnumerable<HostUrlDetails> urlDetails) private static void SetHttpsAndUrls(KestrelServerOptions options, ICollection<(string Url, int Port)> urlDetails)
{ {
foreach (var urlDetail in urlDetails) var urls = urlDetails.Select(u => u.Url);
if (urls.Any(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
{ {
if (urlDetail.IsHttps) options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
{
if (wireMockMiddlewareOptions.CustomCertificateDefined)
{
options.UseHttps(CertificateLoader.LoadCertificate(
wireMockMiddlewareOptions.X509StoreName,
wireMockMiddlewareOptions.X509StoreLocation,
wireMockMiddlewareOptions.X509ThumbprintOrSubjectName,
wireMockMiddlewareOptions.X509CertificateFilePath,
wireMockMiddlewareOptions.X509CertificatePassword,
urlDetail.Host)
);
}
else
{
options.UseHttps(PublicCertificateHelper.GetX509Certificate2());
}
}
} }
} }
} }
internal static class IWebHostBuilderExtensions
{
internal static IWebHostBuilder ConfigureAppConfigurationUsingEnvironmentVariables(this IWebHostBuilder builder) => builder;
internal static IWebHostBuilder ConfigureKestrelServerOptions(this IWebHostBuilder builder)
{
var configuration = new ConfigurationBuilder()
.AddEnvironmentVariables()
.Build();
return builder.ConfigureServices(services =>
{
services.Configure<KestrelServerOptions>(configuration.GetSection("Kestrel"));
});
}
}
} }
#endif #endif

View File

@@ -18,7 +18,7 @@ namespace WireMock.Owin
internal partial class AspNetCoreSelfHost : IOwinSelfHost internal partial class AspNetCoreSelfHost : IOwinSelfHost
{ {
private readonly CancellationTokenSource _cts = new CancellationTokenSource(); private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private readonly IWireMockMiddlewareOptions _wireMockMiddlewareOptions; private readonly IWireMockMiddlewareOptions _options;
private readonly IWireMockLogger _logger; private readonly IWireMockLogger _logger;
private readonly HostUrlOptions _urlOptions; private readonly HostUrlOptions _urlOptions;
@@ -33,14 +33,14 @@ namespace WireMock.Owin
public Exception RunningException => _runningException; public Exception RunningException => _runningException;
public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions wireMockMiddlewareOptions, [NotNull] HostUrlOptions urlOptions) public AspNetCoreSelfHost([NotNull] IWireMockMiddlewareOptions options, [NotNull] HostUrlOptions urlOptions)
{ {
Check.NotNull(wireMockMiddlewareOptions, nameof(wireMockMiddlewareOptions)); Check.NotNull(options, nameof(options));
Check.NotNull(urlOptions, nameof(urlOptions)); Check.NotNull(urlOptions, nameof(urlOptions));
_logger = wireMockMiddlewareOptions.Logger ?? new WireMockConsoleLogger(); _logger = options.Logger ?? new WireMockConsoleLogger();
_wireMockMiddlewareOptions = wireMockMiddlewareOptions; _options = options;
_urlOptions = urlOptions; _urlOptions = urlOptions;
} }
@@ -58,11 +58,9 @@ namespace WireMock.Owin
} }
_host = builder _host = builder
.UseSetting("suppressStatusMessages", "True") // https://andrewlock.net/suppressing-the-startup-and-shutdown-messages-in-asp-net-core/
.ConfigureAppConfigurationUsingEnvironmentVariables()
.ConfigureServices(services => .ConfigureServices(services =>
{ {
services.AddSingleton(_wireMockMiddlewareOptions); services.AddSingleton(_options);
services.AddSingleton<IMappingMatcher, MappingMatcher>(); services.AddSingleton<IMappingMatcher, MappingMatcher>();
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>(); services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>(); services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
@@ -71,19 +69,18 @@ namespace WireMock.Owin
{ {
appBuilder.UseMiddleware<GlobalExceptionMiddleware>(); appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
_wireMockMiddlewareOptions.PreWireMockMiddlewareInit?.Invoke(appBuilder); _options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
appBuilder.UseMiddleware<WireMockMiddleware>(); appBuilder.UseMiddleware<WireMockMiddleware>();
_wireMockMiddlewareOptions.PostWireMockMiddlewareInit?.Invoke(appBuilder); _options.PostWireMockMiddlewareInit?.Invoke(appBuilder);
}) })
.UseKestrel(options => .UseKestrel(options =>
{ {
SetKestrelOptionsLimits(options); SetKestrelOptionsLimits(options);
SetHttpsAndUrls(options, _wireMockMiddlewareOptions, _urlOptions.GetDetails()); SetHttpsAndUrls(options, _urlOptions.GetDetails());
}) })
.ConfigureKestrelServerOptions()
#if NETSTANDARD1_3 #if NETSTANDARD1_3
.UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray()) .UseUrls(_urlOptions.GetDetails().Select(u => u.Url).ToArray())
@@ -108,7 +105,7 @@ namespace WireMock.Owin
{ {
Urls.Add(address.Replace("0.0.0.0", "localhost")); Urls.Add(address.Replace("0.0.0.0", "localhost"));
PortUtils.TryExtract(address, out bool isHttps, out string protocol, out string host, out int port); PortUtils.TryExtract(address, out string protocol, out string host, out int port);
Ports.Add(port); Ports.Add(port);
} }
@@ -121,12 +118,8 @@ namespace WireMock.Owin
_logger.Info("WireMock.Net server using netstandard2.0"); _logger.Info("WireMock.Net server using netstandard2.0");
#elif NETSTANDARD2_1 #elif NETSTANDARD2_1
_logger.Info("WireMock.Net server using netstandard2.1"); _logger.Info("WireMock.Net server using netstandard2.1");
#elif NETCOREAPP3_1
_logger.Info("WireMock.Net server using .NET Core 3.1");
#elif NET5_0
_logger.Info("WireMock.Net server using .NET 5.0");
#elif NET46 #elif NET46
_logger.Info("WireMock.Net server using .NET Framework 4.6.1 or higher"); _logger.Info("WireMock.Net server using .net 4.6.1 or higher");
#endif #endif
#if NETSTANDARD1_3 #if NETSTANDARD1_3

View File

@@ -1,15 +0,0 @@
namespace WireMock.Owin
{
internal class HostUrlDetails
{
public bool IsHttps { get; set; }
public string Url { get; set; }
public string Protocol { get; set; }
public string Host { get; set; }
public int Port { get; set; }
}
}

View File

@@ -5,29 +5,26 @@ namespace WireMock.Owin
{ {
internal class HostUrlOptions internal class HostUrlOptions
{ {
private const string LOCALHOST = "localhost";
public ICollection<string> Urls { get; set; } public ICollection<string> Urls { get; set; }
public int? Port { get; set; } public int? Port { get; set; }
public bool UseSSL { get; set; } public bool UseSSL { get; set; }
public ICollection<HostUrlDetails> GetDetails() public ICollection<(string Url, int Port)> GetDetails()
{ {
var list = new List<HostUrlDetails>(); var list = new List<(string Url, int Port)>();
if (Urls == null) if (Urls == null)
{ {
int port = Port > 0 ? Port.Value : FindFreeTcpPort(); int port = Port > 0 ? Port.Value : FindFreeTcpPort();
string protocol = UseSSL ? "https" : "http"; list.Add(($"{(UseSSL ? "https" : "http")}://localhost:{port}", port));
list.Add(new HostUrlDetails { IsHttps = UseSSL, Url = $"{protocol}://{LOCALHOST}:{port}", Protocol = protocol, Host = LOCALHOST, Port = port });
} }
else else
{ {
foreach (string url in Urls) foreach (string url in Urls)
{ {
PortUtils.TryExtract(url, out bool isHttps, out string protocol, out string host, out int port); PortUtils.TryExtract(url, out string protocol, out string host, out int port);
list.Add(new HostUrlDetails { IsHttps = isHttps, Url = url, Protocol = protocol, Host = host, Port = port }); list.Add((url, port));
} }
} }

View File

@@ -4,6 +4,7 @@ using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Util; using WireMock.Util;
using WireMock.Settings;
#if !USE_ASPNETCORE #if !USE_ASPNETCORE
using Owin; using Owin;
#else #else
@@ -22,6 +23,8 @@ namespace WireMock.Owin
bool? AllowPartialMapping { get; set; } bool? AllowPartialMapping { get; set; }
IPartialMappingSettings PartialMappingSettings { get; set; }
ConcurrentDictionary<Guid, IMapping> Mappings { get; } ConcurrentDictionary<Guid, IMapping> Mappings { get; }
ConcurrentDictionary<string, ScenarioState> Scenarios { get; } ConcurrentDictionary<string, ScenarioState> Scenarios { get; }
@@ -47,17 +50,5 @@ namespace WireMock.Owin
bool? DisableRequestBodyDecompressing { get; set; } bool? DisableRequestBodyDecompressing { get; set; }
bool? HandleRequestsSynchronously { get; set; } bool? HandleRequestsSynchronously { get; set; }
string X509StoreName { get; set; }
string X509StoreLocation { get; set; }
string X509ThumbprintOrSubjectName { get; set; }
string X509CertificateFilePath { get; set; }
string X509CertificatePassword { get; set; }
bool CustomCertificateDefined { get; }
} }
} }

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -80,22 +79,17 @@ namespace WireMock.Owin.Mappers
break; break;
} }
var statusCodeType = responseMessage.StatusCode?.GetType(); switch (responseMessage.StatusCode)
switch (statusCodeType)
{ {
case Type typeAsIntOrEnum when typeAsIntOrEnum == typeof(int) || typeAsIntOrEnum == typeof(int?) || typeAsIntOrEnum.GetTypeInfo().IsEnum: case int statusCodeAsInteger:
response.StatusCode = MapStatusCode((int)responseMessage.StatusCode); response.StatusCode = MapStatusCode(statusCodeAsInteger);
break; break;
case Type typeAsString when typeAsString == typeof(string): case string statusCodeAsString:
// Note: this case will also match on null // Note: this case will also match on null
int.TryParse(responseMessage.StatusCode as string, out int result); int.TryParse(statusCodeAsString, out int result);
response.StatusCode = MapStatusCode(result); response.StatusCode = MapStatusCode(result);
break; break;
default:
break;
} }
SetResponseHeaders(responseMessage, response); SetResponseHeaders(responseMessage, response);

View File

@@ -42,6 +42,16 @@ namespace WireMock.Owin
.OrderBy(m => m.RequestMatchResult) .OrderBy(m => m.RequestMatchResult)
.ThenBy(m => m.Mapping.Priority) .ThenBy(m => m.Mapping.Priority)
.ToList(); .ToList();
if (_options.PartialMappingSettings?.EnforceHttpMethod == true)
{
// Check if any partialMappings contain a HttpMethodMatcher, and check if this returns a 0
foreach (var partialMapping in partialMappings)
{
}
}
var partialMatch = partialMappings.FirstOrDefault(pm => pm.RequestMatchResult.AverageTotalScore > 0.0); var partialMatch = partialMappings.FirstOrDefault(pm => pm.RequestMatchResult.AverageTotalScore > 0.0);
if (_options.AllowPartialMapping == true) if (_options.AllowPartialMapping == true)

View File

@@ -4,6 +4,7 @@ using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Util; using WireMock.Util;
using WireMock.Settings;
#if !USE_ASPNETCORE #if !USE_ASPNETCORE
using Owin; using Owin;
#else #else
@@ -22,6 +23,8 @@ namespace WireMock.Owin
public bool? AllowPartialMapping { get; set; } public bool? AllowPartialMapping { get; set; }
public IPartialMappingSettings PartialMappingSettings { get; set; }
public ConcurrentDictionary<Guid, IMapping> Mappings { get; } = new ConcurrentDictionary<Guid, IMapping>(); public ConcurrentDictionary<Guid, IMapping> Mappings { get; } = new ConcurrentDictionary<Guid, IMapping>();
public ConcurrentDictionary<string, ScenarioState> Scenarios { get; } = new ConcurrentDictionary<string, ScenarioState>(); public ConcurrentDictionary<string, ScenarioState> Scenarios { get; } = new ConcurrentDictionary<string, ScenarioState>();
@@ -53,25 +56,5 @@ namespace WireMock.Owin
/// <inheritdoc cref="IWireMockMiddlewareOptions.HandleRequestsSynchronously"/> /// <inheritdoc cref="IWireMockMiddlewareOptions.HandleRequestsSynchronously"/>
public bool? HandleRequestsSynchronously { get; set; } public bool? HandleRequestsSynchronously { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.X509StoreName"/>
public string X509StoreName { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.X509StoreLocation"/>
public string X509StoreLocation { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.X509ThumbprintOrSubjectName"/>
public string X509ThumbprintOrSubjectName { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.X509CertificateFilePath"/>
public string X509CertificateFilePath { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.X509CertificatePassword"/>
public string X509CertificatePassword { get; set; }
/// <inheritdoc cref="IWireMockMiddlewareOptions.CustomCertificateDefined"/>
public bool CustomCertificateDefined =>
!string.IsNullOrEmpty(X509StoreName) && !string.IsNullOrEmpty(X509StoreLocation) ||
!string.IsNullOrEmpty(X509CertificateFilePath) && !string.IsNullOrEmpty(X509CertificatePassword);
} }
} }

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Threading.Tasks;
using JetBrains.Annotations; using JetBrains.Annotations;
using WireMock.ResponseProviders; using WireMock.ResponseProviders;
@@ -16,12 +15,5 @@ namespace WireMock.ResponseBuilders
/// <returns>The <see cref="IResponseBuilder"/>.</returns> /// <returns>The <see cref="IResponseBuilder"/>.</returns>
[PublicAPI] [PublicAPI]
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, ResponseMessage> callbackHandler); IResponseBuilder WithCallback([NotNull] Func<RequestMessage, ResponseMessage> callbackHandler);
/// <summary>
/// The async callback builder
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
IResponseBuilder WithCallback([NotNull] Func<RequestMessage, Task<ResponseMessage>> callbackHandler);
} }
} }

View File

@@ -1,60 +0,0 @@
using System;
using System.Threading.Tasks;
using WireMock.Validation;
namespace WireMock.ResponseBuilders
{
public partial class Response
{
/// <summary>
/// A delegate to execute to generate the response.
/// </summary>
public Func<RequestMessage, ResponseMessage> Callback { get; private set; }
/// <summary>
/// A delegate to execute to generate the response async.
/// </summary>
public Func<RequestMessage, Task<ResponseMessage>> CallbackAsync { get; private set; }
/// <summary>
/// Defines if the method WithCallback(...) is used.
/// </summary>
public bool WithCallbackUsed { get; private set; }
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback(Func{RequestMessage, ResponseMessage})"/>
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
return WithCallbackInternal(true, callbackHandler);
}
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback(Func{RequestMessage, Task{ResponseMessage}})"/>
public IResponseBuilder WithCallback(Func<RequestMessage, Task<ResponseMessage>> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
return WithCallbackInternal(true, callbackHandler);
}
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
WithCallbackUsed = withCallbackUsed;
Callback = callbackHandler;
return this;
}
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, Task<ResponseMessage>> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
WithCallbackUsed = withCallbackUsed;
CallbackAsync = callbackHandler;
return this;
}
}
}

View File

@@ -42,6 +42,16 @@ namespace WireMock.ResponseBuilders
/// </summary> /// </summary>
public ResponseMessage ResponseMessage { get; } public ResponseMessage ResponseMessage { get; }
/// <summary>
/// A delegate to execute to generate the response.
/// </summary>
public Func<RequestMessage, ResponseMessage> Callback { get; private set; }
/// <summary>
/// Defines if the method WithCallback(...) is used.
/// </summary>
public bool WithCallbackUsed { get; private set; }
/// <summary> /// <summary>
/// Creates this instance. /// Creates this instance.
/// </summary> /// </summary>
@@ -301,6 +311,25 @@ namespace WireMock.ResponseBuilders
return WithDelay(TimeSpan.FromMilliseconds(milliseconds)); return WithDelay(TimeSpan.FromMilliseconds(milliseconds));
} }
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>
public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
return WithCallbackInternal(true, callbackHandler);
}
/// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>
private IResponseBuilder WithCallbackInternal(bool withCallbackUsed, Func<RequestMessage, ResponseMessage> callbackHandler)
{
Check.NotNull(callbackHandler, nameof(callbackHandler));
WithCallbackUsed = withCallbackUsed;
Callback = callbackHandler;
return this;
}
/// <inheritdoc cref="IResponseProvider.ProvideResponseAsync(RequestMessage, IWireMockServerSettings)"/> /// <inheritdoc cref="IResponseProvider.ProvideResponseAsync(RequestMessage, IWireMockServerSettings)"/>
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings) public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
{ {
@@ -336,20 +365,13 @@ namespace WireMock.ResponseBuilders
} }
ResponseMessage responseMessage; ResponseMessage responseMessage;
if (Callback == null && CallbackAsync == null) if (Callback == null)
{ {
responseMessage = ResponseMessage; responseMessage = ResponseMessage;
} }
else else
{ {
if (Callback != null) responseMessage = Callback(requestMessage);
{
responseMessage = Callback(requestMessage);
}
else
{
responseMessage = await CallbackAsync(requestMessage);
}
if (!WithCallbackUsed) if (!WithCallbackUsed)
{ {

View File

@@ -36,7 +36,7 @@ namespace WireMock.Serialization
string matcherName = parts[0]; string matcherName = parts[0];
string matcherType = parts.Length > 1 ? parts[1] : null; string matcherType = parts.Length > 1 ? parts[1] : null;
string[] stringPatterns = (matcher.Patterns != null ? matcher.Patterns : new[] { matcher.Pattern }).OfType<string>().ToArray(); string[] stringPatterns = matcher.Patterns != null ? matcher.Patterns.OfType<string>().ToArray() : new[] { matcher.Pattern as string };
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch; MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
bool ignoreCase = matcher.IgnoreCase == true; bool ignoreCase = matcher.IgnoreCase == true;
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true; bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
@@ -64,12 +64,7 @@ namespace WireMock.Serialization
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails); return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
case "JsonMatcher": case "JsonMatcher":
object value = matcher.Pattern ?? matcher.Patterns; return new JsonMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
return new JsonMatcher(matchBehaviour, value, ignoreCase, throwExceptionWhenMatcherFails);
case "JsonPartialMatcher":
object matcherValue = matcher.Pattern ?? matcher.Patterns;
return new JsonPartialMatcher(matchBehaviour, matcherValue, ignoreCase, throwExceptionWhenMatcherFails);
case "JsonPathMatcher": case "JsonPathMatcher":
return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns); return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);

View File

@@ -367,6 +367,7 @@ namespace WireMock.Server
if (settings.AllowPartialMapping != null) if (settings.AllowPartialMapping != null)
{ {
_options.AllowPartialMapping = settings.AllowPartialMapping.Value; _options.AllowPartialMapping = settings.AllowPartialMapping.Value;
// TODO stef _options.PartialMappingSettings = settings.
} }
if (settings.GlobalProcessingDelay != null) if (settings.GlobalProcessingDelay != null)

View File

@@ -80,7 +80,10 @@ namespace WireMock.Server
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
_httpServer?.StopAsync(); if (_httpServer != null)
{
_httpServer.StopAsync();
}
} }
#endregion #endregion
@@ -227,15 +230,6 @@ namespace WireMock.Server
_options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing; _options.DisableJsonBodyParsing = _settings.DisableJsonBodyParsing;
_options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously; _options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
if (settings.CustomCertificateDefined)
{
_options.X509StoreName = settings.CertificateSettings.X509StoreName;
_options.X509StoreLocation = settings.CertificateSettings.X509StoreLocation;
_options.X509ThumbprintOrSubjectName = settings.CertificateSettings.X509StoreThumbprintOrSubjectName;
_options.X509CertificateFilePath = settings.CertificateSettings.X509CertificateFilePath;
_options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword;
}
_matcherMapper = new MatcherMapper(_settings); _matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper); _mappingConverter = new MappingConverter(_matcherMapper);
@@ -289,7 +283,7 @@ namespace WireMock.Server
if (settings.AllowPartialMapping == true) if (settings.AllowPartialMapping == true)
{ {
AllowPartialMapping(); AllowPartialMapping(true, settings.PartialMappingSettings);
} }
if (settings.StartAdminInterface == true) if (settings.StartAdminInterface == true)
@@ -395,10 +389,21 @@ namespace WireMock.Server
/// <inheritdoc cref="IWireMockServer.AllowPartialMapping" /> /// <inheritdoc cref="IWireMockServer.AllowPartialMapping" />
[PublicAPI] [PublicAPI]
public void AllowPartialMapping(bool allow = true) public void AllowPartialMapping(bool allow = true, bool enforceHttpMethod = false)
{
AllowPartialMapping(allow, new PartialMappingSettings
{
EnforceHttpMethod = enforceHttpMethod
});
}
/// <inheritdoc cref="IWireMockServer.AllowPartialMapping" />
[PublicAPI]
public void AllowPartialMapping(bool allow = true, IPartialMappingSettings partialMappingSettings = null)
{ {
_settings.Logger.Info("AllowPartialMapping is set to {0}", allow); _settings.Logger.Info("AllowPartialMapping is set to {0}", allow);
_options.AllowPartialMapping = allow; _options.AllowPartialMapping = allow;
_options.PartialMappingSettings = partialMappingSettings;
} }
/// <inheritdoc cref="IWireMockServer.SetBasicAuthentication" /> /// <inheritdoc cref="IWireMockServer.SetBasicAuthentication" />

View File

@@ -0,0 +1,13 @@
namespace WireMock.Settings
{
/// <summary>
/// IPartialMappingSettings
/// </summary>
public interface IPartialMappingSettings
{
/// <summary>
/// ...
/// </summary>
bool EnforceHttpMethod { get; set; }
}
}

View File

@@ -1,44 +0,0 @@
namespace WireMock.Settings
{
/// <summary>
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
///
/// X509StoreName and X509StoreLocation should be defined
/// OR
/// X509CertificateFilePath and X509CertificatePassword should be defined
/// </summary>
public interface IWireMockCertificateSettings
{
/// <summary>
/// X509 StoreName (AddressBook, AuthRoot, CertificateAuthority, My, Root, TrustedPeople or TrustedPublisher)
/// </summary>
string X509StoreName { get; set; }
/// <summary>
/// X509 StoreLocation (CurrentUser or LocalMachine)
/// </summary>
string X509StoreLocation { get; set; }
/// <summary>
/// X509 Thumbprint or SubjectName (if not defined, the 'host' is used)
/// </summary>
string X509StoreThumbprintOrSubjectName { get; set; }
/// <summary>
/// X509Certificate FilePath
/// </summary>
string X509CertificateFilePath { get; set; }
/// <summary>
/// X509Certificate Password
/// </summary>
string X509CertificatePassword { get; set; }
/// <summary>
/// X509StoreName and X509StoreLocation should be defined
/// OR
/// X509CertificateFilePath and X509CertificatePassword should be defined
/// </summary>
bool IsDefined { get; }
}
}

View File

@@ -73,6 +73,12 @@ namespace WireMock.Settings
[PublicAPI] [PublicAPI]
bool? AllowPartialMapping { get; set; } bool? AllowPartialMapping { get; set; }
/// <summary>
/// Gets or sets the partial mapping settings (optional).
/// </summary>
[PublicAPI]
IPartialMappingSettings PartialMappingSettings { get; set; }
/// <summary> /// <summary>
/// The username needed for __admin access. /// The username needed for __admin access.
/// </summary> /// </summary>
@@ -170,21 +176,5 @@ namespace WireMock.Settings
/// </summary> /// </summary>
[PublicAPI] [PublicAPI]
bool? ThrowExceptionWhenMatcherFails { get; set; } bool? ThrowExceptionWhenMatcherFails { get; set; }
/// <summary>
/// If https is used, these settings can be used to configure the CertificateSettings in case a custom certificate instead the default .NET certificate should be used.
///
/// X509StoreName and X509StoreLocation should be defined
/// OR
/// X509CertificateFilePath and X509CertificatePassword should be defined
/// </summary>
[PublicAPI]
IWireMockCertificateSettings CertificateSettings { get; set; }
/// <summary>
/// Defines if custom CertificateSettings are defined
/// </summary>
[PublicAPI]
bool CustomCertificateDefined { get; }
} }
} }

View File

@@ -0,0 +1,15 @@
using JetBrains.Annotations;
namespace WireMock.Settings
{
/// <summary>
/// PartialMappingSettings
/// </summary>
/// <seealso cref="IPartialMappingSettings" />
public class PartialMappingSettings : IPartialMappingSettings
{
/// <inheritdoc cref="IPartialMappingSettings.EnforceHttpMethod"/>
[PublicAPI]
public bool EnforceHttpMethod { get; set; }
}
}

View File

@@ -9,7 +9,7 @@ namespace WireMock.Settings
{ {
private const string Sigil = "--"; private const string Sigil = "--";
private IDictionary<string, string[]> Arguments { get; } = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase); private IDictionary<string, string[]> Arguments { get; } = new Dictionary<string, string[]>();
public void Parse(string[] arguments) public void Parse(string[] arguments)
{ {
@@ -70,11 +70,6 @@ namespace WireMock.Settings
}, defaultValue); }, defaultValue);
} }
public bool GetBoolSwitchValue(string name)
{
return Contains(name);
}
public int? GetIntValue(string name, int? defaultValue = null) public int? GetIntValue(string name, int? defaultValue = null)
{ {
return GetValue(name, values => return GetValue(name, values =>

View File

@@ -1,36 +0,0 @@
using JetBrains.Annotations;
namespace WireMock.Settings
{
/// <summary>
/// <see cref="IWireMockCertificateSettings"/>
/// </summary>
public class WireMockCertificateSettings : IWireMockCertificateSettings
{
/// <inheritdoc cref="IWireMockCertificateSettings.X509StoreName"/>
[PublicAPI]
public string X509StoreName { get; set; }
/// <inheritdoc cref="IWireMockCertificateSettings.X509StoreLocation"/>
[PublicAPI]
public string X509StoreLocation { get; set; }
/// <inheritdoc cref="IWireMockCertificateSettings.X509StoreThumbprintOrSubjectName"/>
[PublicAPI]
public string X509StoreThumbprintOrSubjectName { get; set; }
/// <inheritdoc cref="IWireMockCertificateSettings.X509CertificateFilePath"/>
[PublicAPI]
public string X509CertificateFilePath { get; set; }
/// <inheritdoc cref="IWireMockCertificateSettings.X509CertificatePassword"/>
[PublicAPI]
public string X509CertificatePassword { get; set; }
/// <inheritdoc cref="IWireMockCertificateSettings.IsDefined"/>
[PublicAPI]
public bool IsDefined =>
!string.IsNullOrEmpty(X509StoreName) && !string.IsNullOrEmpty(X509StoreLocation) ||
!string.IsNullOrEmpty(X509CertificateFilePath) && !string.IsNullOrEmpty(X509CertificatePassword);
}
}

View File

@@ -1,6 +1,6 @@
using System; using HandlebarsDotNet;
using HandlebarsDotNet;
using JetBrains.Annotations; using JetBrains.Annotations;
using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
@@ -53,6 +53,10 @@ namespace WireMock.Settings
[PublicAPI] [PublicAPI]
public bool? AllowPartialMapping { get; set; } public bool? AllowPartialMapping { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.PartialMappingSettings"/>
[PublicAPI]
public IPartialMappingSettings PartialMappingSettings { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.AdminUsername"/> /// <inheritdoc cref="IWireMockServerSettings.AdminUsername"/>
[PublicAPI] [PublicAPI]
public string AdminUsername { get; set; } public string AdminUsername { get; set; }
@@ -121,13 +125,5 @@ namespace WireMock.Settings
/// <inheritdoc cref="IWireMockServerSettings.ThrowExceptionWhenMatcherFails"/> /// <inheritdoc cref="IWireMockServerSettings.ThrowExceptionWhenMatcherFails"/>
[PublicAPI] [PublicAPI]
public bool? ThrowExceptionWhenMatcherFails { get; set; } public bool? ThrowExceptionWhenMatcherFails { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.CertificateSettings"/>
[PublicAPI]
public IWireMockCertificateSettings CertificateSettings { get; set; }
/// <inheritdoc cref="IWireMockServerSettings.CustomCertificateDefined"/>
[PublicAPI]
public bool CustomCertificateDefined => CertificateSettings?.IsDefined == true;
} }
} }

View File

@@ -14,23 +14,15 @@ namespace WireMock.Settings
/// </summary> /// </summary>
/// <param name="args">The commandline arguments</param> /// <param name="args">The commandline arguments</param>
/// <param name="logger">The logger (optional, can be null)</param> /// <param name="logger">The logger (optional, can be null)</param>
/// <param name="settings">The parsed settings</param>
[PublicAPI] [PublicAPI]
public static bool TryParseArguments([NotNull] string[] args, out IWireMockServerSettings settings, [CanBeNull] IWireMockLogger logger = null) public static IWireMockServerSettings ParseArguments([NotNull] string[] args, [CanBeNull] IWireMockLogger logger = null)
{ {
Check.HasNoNulls(args, nameof(args)); Check.HasNoNulls(args, nameof(args));
var parser = new SimpleCommandLineParser(); var parser = new SimpleCommandLineParser();
parser.Parse(args); parser.Parse(args);
if (parser.GetBoolSwitchValue("help")) var settings = new WireMockServerSettings
{
(logger ?? new WireMockConsoleLogger()).Info("See https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-commandline-parameters for details on all commandline options.");
settings = null;
return false;
}
settings = new WireMockServerSettings
{ {
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true), StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"), ReadStaticMappings = parser.GetBoolValue("ReadStaticMappings"),
@@ -68,12 +60,12 @@ namespace WireMock.Settings
settings.Urls = parser.GetValues("Urls", new[] { "http://*:9091/" }); settings.Urls = parser.GetValues("Urls", new[] { "http://*:9091/" });
} }
string proxyUrl = parser.GetStringValue("ProxyURL") ?? parser.GetStringValue("ProxyUrl"); string proxyURL = parser.GetStringValue("ProxyURL");
if (!string.IsNullOrEmpty(proxyUrl)) if (!string.IsNullOrEmpty(proxyURL))
{ {
settings.ProxyAndRecordSettings = new ProxyAndRecordSettings settings.ProxyAndRecordSettings = new ProxyAndRecordSettings
{ {
Url = proxyUrl, Url = proxyURL,
SaveMapping = parser.GetBoolValue("SaveMapping"), SaveMapping = parser.GetBoolValue("SaveMapping"),
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"), SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern"), SaveMappingForStatusCodePattern = parser.GetStringValue("SaveMappingForStatusCodePattern"),
@@ -95,20 +87,7 @@ namespace WireMock.Settings
} }
} }
var certificateSettings = new WireMockCertificateSettings return settings;
{
X509StoreName = parser.GetStringValue("X509StoreName"),
X509StoreLocation = parser.GetStringValue("X509StoreLocation"),
X509StoreThumbprintOrSubjectName = parser.GetStringValue("X509StoreThumbprintOrSubjectName"),
X509CertificateFilePath = parser.GetStringValue("X509CertificateFilePath"),
X509CertificatePassword = parser.GetStringValue("X509CertificatePassword")
};
if (certificateSettings.IsDefined)
{
settings.CertificateSettings = certificateSettings;
}
return true;
} }
} }
} }

View File

@@ -1,5 +1,4 @@
using System; using System.Net;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
@@ -33,23 +32,21 @@ namespace WireMock.Util
} }
/// <summary> /// <summary>
/// Extract the if-isHttps, protocol, host and port from a URL. /// Extract the protocol, host and port from a URL.
/// </summary> /// </summary>
public static bool TryExtract(string url, out bool isHttps, out string protocol, out string host, out int port) public static bool TryExtract(string url, out string protocol, out string host, out int port)
{ {
isHttps = false;
protocol = null; protocol = null;
host = null; host = null;
port = default; port = default(int);
var match = UrlDetailsRegex.Match(url); Match m = UrlDetailsRegex.Match(url);
if (match.Success) if (m.Success)
{ {
protocol = match.Groups["proto"].Value; protocol = m.Groups["proto"].Value;
isHttps = protocol.StartsWith("https", StringComparison.OrdinalIgnoreCase); host = m.Groups["host"].Value;
host = match.Groups["host"].Value;
return int.TryParse(match.Groups["port"].Value, out port); return int.TryParse(m.Groups["port"].Value, out port);
} }
return false; return false;

View File

@@ -3,7 +3,7 @@
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description> <Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
<AssemblyTitle>WireMock.Net</AssemblyTitle> <AssemblyTitle>WireMock.Net</AssemblyTitle>
<Authors>Stef Heyenrath</Authors> <Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0</TargetFrameworks> <TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netstandard2.1;netcoreapp3.1</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net</AssemblyName> <AssemblyName>WireMock.Net</AssemblyName>
<PackageId>WireMock.Net</PackageId> <PackageId>WireMock.Net</PackageId>
@@ -42,7 +42,7 @@
<DefineConstants>NETSTANDARD;USE_ASPNETCORE</DefineConstants> <DefineConstants>NETSTANDARD;USE_ASPNETCORE</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1' or '$(TargetFramework)' == 'netcoreapp2.2' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0'"> <PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1' or '$(TargetFramework)' == 'netcoreapp2.2' or '$(TargetFramework)' == 'netcoreapp3.1'">
<DefineConstants>USE_ASPNETCORE</DefineConstants> <DefineConstants>USE_ASPNETCORE</DefineConstants>
</PropertyGroup> </PropertyGroup>
@@ -58,7 +58,7 @@
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" /> <PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" />
<PackageReference Include="JmesPath.Net" Version="1.0.125" /> <PackageReference Include="JmesPath.Net" Version="1.0.125" />
<PackageReference Include="Handlebars.Net.Helpers" Version="1.1.0" /> <PackageReference Include="Handlebars.Net.Helpers" Version="1.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Debug - Sonar'"> <ItemGroup Condition="'$(Configuration)' == 'Debug - Sonar'">
@@ -141,12 +141,6 @@
<PackageReference Include="CS-Script.Core" Version="1.4.0" /> <PackageReference Include="CS-Script.Core" Version="1.4.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net5.0'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<!-- https://github.com/WireMock-Net/WireMock.Net/issues/448 -->
<PackageReference Include="CS-Script.Core" Version="1.4.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" /> <ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -1,58 +0,0 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using WireMock.Net.StandAlone;
using WireMock.Server;
namespace WireMock
{
public class Program
{
private static int SleepTime = 30000;
private static readonly ILogger Logger = LoggerFactory.Create(o =>
{
o.SetMinimumLevel(LogLevel.Debug);
o.AddSimpleConsole(options =>
{
options.IncludeScopes = true;
options.SingleLine = false;
options.TimestampFormat = "yyyy-MM-ddTHH:mm:ss ";
});
}).CreateLogger(string.Empty);
private static WireMockServer Server;
static async Task Main(string[] args)
{
if (!StandAloneApp.TryStart(args, out Server, new WireMockLogger(Logger)))
{
return;
}
Logger.LogInformation("Press Ctrl+C to shut down");
Console.CancelKeyPress += (s, e) =>
{
Stop("CancelKeyPress");
};
System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += ctx =>
{
Stop("AssemblyLoadContext.Default.Unloading");
};
while (true)
{
Logger.LogInformation("WireMock.Net server running : {IsStarted}", Server.IsStarted);
await Task.Delay(SleepTime);
}
}
private static void Stop(string why)
{
Logger.LogInformation("WireMock.Net server stopping because '{why}'", why);
Server.Stop();
Logger.LogInformation("WireMock.Net server stopped");
}
}
}

View File

@@ -1,8 +0,0 @@
{
"profiles": {
"dotnet-WireMock.Net": {
"commandName": "Project",
"commandLineArgs": ""
}
}
}

View File

@@ -1,61 +0,0 @@
using System;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using WireMock.Admin.Requests;
using WireMock.Logging;
namespace WireMock
{
public class WireMockLogger : IWireMockLogger
{
private readonly JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true
};
private readonly ILogger _logger;
public WireMockLogger(ILogger logger)
{
_logger = logger;
}
/// <see cref="IWireMockLogger.Debug"/>
public void Debug(string formatString, params object[] args)
{
_logger.LogDebug(formatString, args);
}
/// <see cref="IWireMockLogger.Info"/>
public void Info(string formatString, params object[] args)
{
_logger.LogInformation(formatString, args);
}
/// <see cref="IWireMockLogger.Warn"/>
public void Warn(string formatString, params object[] args)
{
_logger.LogWarning(formatString, args);
}
/// <see cref="IWireMockLogger.Error(string, object[])"/>
public void Error(string formatString, params object[] args)
{
_logger.LogError(formatString, args);
}
/// <see cref="IWireMockLogger.Error(string, Exception)"/>
public void Error(string formatString, Exception exception)
{
_logger.LogError(formatString, exception);
}
/// <see cref="IWireMockLogger.DebugRequestResponse"/>
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
{
string message = JsonSerializer.Serialize(logEntryModel, options);
_logger.LogDebug("Admin[{IsAdmin}] {Message}", isAdminRequest, message);
}
}
}

View File

@@ -1,27 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PackAsTool>true</PackAsTool>
<ToolCommandName>dotnet-wiremock</ToolCommandName>
<Description>A dotnet commandline tool for WireMock.Net (A Lightweight Http Mocking Server for .NET)</Description>
<PackageTags>tdd;mock;http;wiremock;test;server;unittest;dotnet;tool;dotnet-tool</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Authors>Stef Heyenrath</Authors>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\WireMock.Net.StandAlone\WireMock.Net.StandAlone.csproj" />
</ItemGroup>
</Project>

View File

@@ -9,25 +9,24 @@ using WireMock.Server;
using Xunit; using Xunit;
using WireMock.FluentAssertions; using WireMock.FluentAssertions;
using System.Threading.Tasks; using System.Threading.Tasks;
using WireMock.Settings;
using static System.Environment; using static System.Environment;
namespace WireMock.Net.Tests.FluentAssertions namespace WireMock.Net.Tests.FluentAssertions
{ {
public class WireMockAssertionsTests : IDisposable public class WireMockAssertionsTests : IDisposable
{ {
private readonly WireMockServer _server; private WireMockServer _server;
private readonly HttpClient _httpClient; private HttpClient _httpClient;
private readonly int _portUsed; private int _portUsed;
public WireMockAssertionsTests() public WireMockAssertionsTests()
{ {
_server = WireMockServer.Start(); _server = WireMockServer.Start();
_server.Given(Request.Create().UsingAnyMethod()) _server.Given(Request.Create().UsingAnyMethod())
.RespondWith(Response.Create().WithSuccess()); .RespondWith(Response.Create().WithStatusCode(200));
_portUsed = _server.Ports.First(); _portUsed = _server.Ports.First();
_httpClient = new HttpClient { BaseAddress = new Uri(_server.Urls[0]) }; _httpClient = new HttpClient { BaseAddress = new Uri($"http://localhost:{_portUsed}") };
} }
[Fact] [Fact]
@@ -157,139 +156,10 @@ namespace WireMock.Net.Tests.FluentAssertions
.Be($"{string.Join(NewLine, missingValue1Message, missingValue2Message)}{NewLine}"); .Be($"{string.Join(NewLine, missingValue1Message, missingValue2Message)}{NewLine}");
} }
[Fact]
public async Task AtUrl_WhenACallWasMadeToUrl_Should_BeOK()
{
await _httpClient.GetAsync("anyurl");
_server.Should()
.HaveReceivedACall()
.AtUrl($"http://localhost:{_portUsed}/anyurl");
}
[Fact]
public void AtUrl_Should_ThrowWhenNoCallsWereMade()
{
Action act = () => _server.Should()
.HaveReceivedACall()
.AtUrl("anyurl");
act.Should().Throw<Exception>()
.And.Message.Should()
.Be(
"Expected _server to have been called at address matching the url \"anyurl\", but no calls were made.");
}
[Fact]
public async Task AtUrl_Should_ThrowWhenNoCallsMatchingTheUrlWereMade()
{
await _httpClient.GetAsync("");
Action act = () => _server.Should()
.HaveReceivedACall()
.AtUrl("anyurl");
act.Should().Throw<Exception>()
.And.Message.Should()
.Be(
$"Expected _server to have been called at address matching the url \"anyurl\", but didn't find it among the calls to {{\"http://localhost:{_portUsed}/\"}}.");
}
[Fact]
public async Task WithProxyUrl_WhenACallWasMadeWithProxyUrl_Should_BeOK()
{
_server.ResetMappings();
_server.Given(Request.Create().UsingAnyMethod())
.RespondWith(Response.Create().WithProxy(new ProxyAndRecordSettings {Url = "http://localhost:9999"}));
await _httpClient.GetAsync("");
_server.Should()
.HaveReceivedACall()
.WithProxyUrl($"http://localhost:9999");
}
[Fact]
public void WithProxyUrl_Should_ThrowWhenNoCallsWereMade()
{
_server.ResetMappings();
_server.Given(Request.Create().UsingAnyMethod())
.RespondWith(Response.Create().WithProxy(new ProxyAndRecordSettings {Url = "http://localhost:9999"}));
Action act = () => _server.Should()
.HaveReceivedACall()
.WithProxyUrl("anyurl");
act.Should().Throw<Exception>()
.And.Message.Should()
.Be(
"Expected _server to have been called with proxy url \"anyurl\", but no calls were made.");
}
[Fact]
public async Task WithProxyUrl_Should_ThrowWhenNoCallsWithTheProxyUrlWereMade()
{
_server.ResetMappings();
_server.Given(Request.Create().UsingAnyMethod())
.RespondWith(Response.Create().WithProxy(new ProxyAndRecordSettings {Url = "http://localhost:9999"}));
await _httpClient.GetAsync("");
Action act = () => _server.Should()
.HaveReceivedACall()
.WithProxyUrl("anyurl");
act.Should().Throw<Exception>()
.And.Message.Should()
.Be(
$"Expected _server to have been called with proxy url \"anyurl\", but didn't find it among the calls with {{\"http://localhost:9999\"}}.");
}
[Fact]
public async Task FromClientIP_whenACallWasMadeFromClientIP_Should_BeOK()
{
await _httpClient.GetAsync("");
var clientIP = _server.LogEntries.Last().RequestMessage.ClientIP;
_server.Should()
.HaveReceivedACall()
.FromClientIP(clientIP);
}
[Fact]
public void FromClientIP_Should_ThrowWhenNoCallsWereMade()
{
Action act = () => _server.Should()
.HaveReceivedACall()
.FromClientIP("different-ip");
act.Should().Throw<Exception>()
.And.Message.Should()
.Be(
"Expected _server to have been called from client IP \"different-ip\", but no calls were made.");
}
[Fact]
public async Task FromClientIP_Should_ThrowWhenNoCallsFromClientIPWereMade()
{
await _httpClient.GetAsync("");
var clientIP = _server.LogEntries.Last().RequestMessage.ClientIP;
Action act = () => _server.Should()
.HaveReceivedACall()
.FromClientIP("different-ip");
act.Should().Throw<Exception>()
.And.Message.Should()
.Be(
$"Expected _server to have been called from client IP \"different-ip\", but didn't find it among the calls from IP(s) {{\"{clientIP}\"}}.");
}
public void Dispose() public void Dispose()
{ {
_server?.Stop(); _server?.Stop();
_server?.Dispose(); _server?.Dispose();
_httpClient?.Dispose();
} }
} }
} }

View File

@@ -1,385 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using FluentAssertions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NFluent;
using WireMock.Matchers;
using Xunit;
namespace WireMock.Net.Tests.Matchers
{
public class JsonPartialMatcherTests
{
[Fact]
public void JsonPartialMatcher_GetName()
{
// Assign
var matcher = new JsonPartialMatcher("{}");
// Act
string name = matcher.Name;
// Assert
Check.That(name).Equals("JsonPartialMatcher");
}
[Fact]
public void JsonPartialMatcher_GetValue()
{
// Assign
var matcher = new JsonPartialMatcher("{}");
// Act
object value = matcher.Value;
// Assert
Check.That(value).Equals("{}");
}
[Fact]
public void JsonPartialMatcher_WithInvalidStringValue_Should_ThrowException()
{
// Act
Action action = () => new JsonPartialMatcher(MatchBehaviour.AcceptOnMatch, "{ \"Id\"");
// Assert
action.Should().Throw<JsonException>();
}
[Fact]
public void JsonPartialMatcher_WithInvalidObjectValue_Should_ThrowException()
{
// Act
Action action = () => new JsonPartialMatcher(MatchBehaviour.AcceptOnMatch, new MemoryStream());
// Assert
action.Should().Throw<JsonException>();
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsFalse_Should_ReturnMismatch()
{
// Assign
var matcher = new JsonPartialMatcher("");
// Act
double match = matcher.IsMatch(new MemoryStream());
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithInvalidValue_And_ThrowExceptionIsTrue_Should_ReturnMismatch()
{
// Assign
var matcher = new JsonPartialMatcher("", false, true);
// Act
Action action = () => matcher.IsMatch(new MemoryStream());
// Assert
action.Should().Throw<JsonException>();
}
[Fact]
public void JsonPartialMatcher_IsMatch_ByteArray()
{
// Assign
var bytes = new byte[0];
var matcher = new JsonPartialMatcher("");
// Act
double match = matcher.IsMatch(bytes);
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonPartialMatcher_IsMatch_NullString()
{
// Assign
string s = null;
var matcher = new JsonPartialMatcher("");
// Act
double match = matcher.IsMatch(s);
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonPartialMatcher_IsMatch_NullObject()
{
// Assign
object o = null;
var matcher = new JsonPartialMatcher("");
// Act
double match = matcher.IsMatch(o);
// Assert
Check.That(match).IsEqualTo(0);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JArray()
{
// Assign
var matcher = new JsonPartialMatcher(new[] { "x", "y" });
// Act
var jArray = new JArray
{
"x",
"y"
};
double match = matcher.IsMatch(jArray);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JObject()
{
// Assign
var matcher = new JsonPartialMatcher(new { Id = 1, Name = "Test" });
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithIgnoreCaseTrue_JObject()
{
// Assign
var matcher = new JsonPartialMatcher(new { id = 1, Name = "test" }, true);
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "NaMe", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JObjectParsed()
{
// Assign
var matcher = new JsonPartialMatcher(new { Id = 1, Name = "Test" });
// Act
var jobject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithIgnoreCaseTrue_JObjectParsed()
{
// Assign
var matcher = new JsonPartialMatcher(new { Id = 1, Name = "TESt" }, true);
// Act
var jobject = JObject.Parse("{ \"Id\" : 1, \"Name\" : \"Test\" }");
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JArrayAsString()
{
// Assign
var matcher = new JsonPartialMatcher("[ \"x\", \"y\" ]");
// Act
var jArray = new JArray
{
"x",
"y"
};
double match = matcher.IsMatch(jArray);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JObjectAsString()
{
// Assign
var matcher = new JsonPartialMatcher("{ \"Id\" : 1, \"Name\" : \"Test\" }");
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithIgnoreCaseTrue_JObjectAsString()
{
// Assign
var matcher = new JsonPartialMatcher("{ \"Id\" : 1, \"Name\" : \"test\" }", true);
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JObjectAsString_RejectOnMatch()
{
// Assign
var matcher = new JsonPartialMatcher(MatchBehaviour.RejectOnMatch, "{ \"Id\" : 1, \"Name\" : \"Test\" }");
// Act
var jobject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue("Test") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(0.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_JObjectWithDateTimeOffsetAsString()
{
// Assign
var matcher = new JsonPartialMatcher("{ \"preferredAt\" : \"2019-11-21T10:32:53.2210009+00:00\" }");
// Act
var jobject = new JObject
{
{ "preferredAt", new JValue("2019-11-21T10:32:53.2210009+00:00") }
};
double match = matcher.IsMatch(jobject);
// Assert
Assert.Equal(1.0, match);
}
[Theory]
[InlineData("{\"test\":\"abc\"}", "{\"test\":\"abc\",\"other\":\"xyz\"}")]
[InlineData("\"test\"", "\"test\"")]
[InlineData("123", "123")]
[InlineData("[\"test\"]", "[\"test\"]")]
[InlineData("[\"test\"]", "[\"test\", \"other\"]")]
[InlineData("[123]", "[123]")]
[InlineData("[123]", "[123, 456]")]
[InlineData("{ \"test\":\"value\" }", "{\"test\":\"value\",\"other\":123}")]
[InlineData("{ \"test\":\"value\" }", "{\"test\":\"value\"}")]
[InlineData("{\"test\":{\"nested\":\"value\"}}", "{\"test\":{\"nested\":\"value\"}}")]
public void JsonPartialMatcher_IsMatch_StringInputValidMatch(string value, string input)
{
// Assign
var matcher = new JsonPartialMatcher(value);
// Act
double match = matcher.IsMatch(input);
// Assert
Assert.Equal(1.0, match);
}
[Theory]
[InlineData("\"test\"", null)]
[InlineData("\"test1\"", "\"test2\"")]
[InlineData("123", "1234")]
[InlineData("[\"test\"]", "[\"test1\"]")]
[InlineData("[\"test\"]", "[\"test1\", \"test2\"]")]
[InlineData("[123]", "[1234]")]
[InlineData("{}", "\"test\"")]
[InlineData("{ \"test\":\"value\" }", "{\"test\":\"value2\"}")]
[InlineData("{ \"test.nested\":\"value\" }", "{\"test\":{\"nested\":\"value1\"}}")]
[InlineData("{\"test\":{\"test1\":\"value\"}}", "{\"test\":{\"test1\":\"value1\"}}")]
[InlineData("[{ \"test.nested\":\"value\" }]", "[{\"test\":{\"nested\":\"value1\"}}]")]
public void JsonPartialMatcher_IsMatch_StringInputWithInvalidMatch(string value, string input)
{
// Assign
var matcher = new JsonPartialMatcher(value);
// Act
double match = matcher.IsMatch(input);
// Assert
Assert.Equal(0.0, match);
}
[Theory]
[InlineData("{ \"test.nested\":123 }", "{\"test\":{\"nested\":123}}")]
[InlineData("{ \"test.nested\":[123, 456] }", "{\"test\":{\"nested\":[123, 456]}}")]
[InlineData("{ \"test.nested\":\"value\" }", "{\"test\":{\"nested\":\"value\"}}")]
[InlineData("{ \"['name.with.dot']\":\"value\" }", "{\"name.with.dot\":\"value\"}")]
[InlineData("[{ \"test.nested\":\"value\" }]", "[{\"test\":{\"nested\":\"value\"}}]")]
[InlineData("[{ \"['name.with.dot']\":\"value\" }]", "[{\"name.with.dot\":\"value\"}]")]
public void JsonPartialMatcher_IsMatch_ValueAsJPathValidMatch(string value, string input)
{
// Assign
var matcher = new JsonPartialMatcher(value);
// Act
double match = matcher.IsMatch(input);
// Assert
Assert.Equal(1.0, match);
}
[Theory]
[InlineData("{ \"test.nested\":123 }", "{\"test\":{\"nested\":456}}")]
[InlineData("{ \"test.nested\":[123, 456] }", "{\"test\":{\"nested\":[1, 2]}}")]
[InlineData("{ \"test.nested\":\"value\" }", "{\"test\":{\"nested\":\"value1\"}}")]
[InlineData("{ \"['name.with.dot']\":\"value\" }", "{\"name.with.dot\":\"value1\"}")]
[InlineData("[{ \"test.nested\":\"value\" }]", "[{\"test\":{\"nested\":\"value1\"}}]")]
[InlineData("[{ \"['name.with.dot']\":\"value\" }]", "[{\"name.with.dot\":\"value1\"}]")]
public void JsonPartialMatcher_IsMatch_ValueAsJPathInvalidMatch(string value, string input)
{
// Assign
var matcher = new JsonPartialMatcher(value);
// Act
double match = matcher.IsMatch(input);
// Assert
Assert.Equal(0.0, match);
}
}
}

View File

@@ -69,8 +69,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(count).Equals(1); Check.That(count).Equals(1);
server.Dispose();
} }
[Fact] [Fact]
@@ -107,8 +105,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(countResponsesWithStatusNotOk).Equals(0); Check.That(countResponsesWithStatusNotOk).Equals(0);
Check.That(count).Equals(expectedCount); Check.That(count).Equals(expectedCount);
server.Dispose();
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using NFluent; using System.Collections.Generic;
using System.Collections.Generic; using FluentAssertions;
using NFluent;
using WireMock.Matchers.Request; using WireMock.Matchers.Request;
using WireMock.Models; using WireMock.Models;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
@@ -13,6 +14,34 @@ namespace WireMock.Net.Tests
{ {
private const string ClientIp = "::1"; private const string ClientIp = "::1";
[Fact]
public void Should_Match_When_Verb_Does_Match()
{
// Arrange
var requestPut = Request.Create().WithPath("/bar").UsingPut();
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/bar"), "PUT", ClientIp);
// Assert
var requestMatchResult = new RequestMatchResult();
requestPut.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
[Fact]
public void Should_NotMatch_When_Verb_Does_Not_Match()
{
// Arrange
var requestGet = Request.Create().WithPath("/bar").UsingGet();
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/bar"), "PUT", ClientIp);
// Assert
var requestMatchResult = new RequestMatchResult();
requestGet.GetMatchingScore(request, requestMatchResult).Should().Be(0.0);
}
[Fact] [Fact]
public void Should_exclude_requests_matching_given_http_method_but_not_url() public void Should_exclude_requests_matching_given_http_method_but_not_url()
{ {

View File

@@ -41,8 +41,6 @@ namespace WireMock.Net.Tests.ResponseBuilders
// Assert // Assert
response.Should().Contain("<hello>world</hello>"); response.Should().Contain("<hello>world</hello>");
server.Stop();
} }
[Fact] [Fact]
@@ -72,8 +70,6 @@ namespace WireMock.Net.Tests.ResponseBuilders
// Assert // Assert
response.Should().Contain("<hello>world</hello>"); response.Should().Contain("<hello>world</hello>");
server.Stop();
} }
[Fact] [Fact]
@@ -103,8 +99,6 @@ namespace WireMock.Net.Tests.ResponseBuilders
// Assert // Assert
response.Should().Contain("<hello>world</hello>"); response.Should().Contain("<hello>world</hello>");
server.Stop();
} }
} }
} }

View File

@@ -13,35 +13,6 @@ namespace WireMock.Net.Tests.ResponseBuilders
{ {
private readonly WireMockServerSettings _settings = new WireMockServerSettings(); private readonly WireMockServerSettings _settings = new WireMockServerSettings();
[Fact]
public async Task Response_WithCallbackAsync()
{
// Assign
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
var response = Response.Create()
.WithCallback(async request =>
{
await Task.Delay(1);
return new ResponseMessage
{
BodyData = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = request.Path + "Bar"
},
StatusCode = 302
};
});
// Act
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
// Assert
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
responseMessage.StatusCode.Should().Be(302);
}
[Fact] [Fact]
public async Task Response_WithCallback() public async Task Response_WithCallback()
{ {

View File

@@ -82,7 +82,6 @@ namespace WireMock.Net.Tests.ResponseBuilders
public void Dispose() public void Dispose()
{ {
_server?.Stop();
_server?.Dispose(); _server?.Dispose();
} }
} }

View File

@@ -1,7 +1,6 @@
using System; using Moq;
using FluentAssertions;
using Moq;
using NFluent; using NFluent;
using System;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Serialization; using WireMock.Serialization;
@@ -27,7 +26,7 @@ namespace WireMock.Net.Tests.Serialization
var model = _sut.Map((IMatcher)null); var model = _sut.Map((IMatcher)null);
// Assert // Assert
model.Should().BeNull(); Check.That(model).IsNull();
} }
[Fact] [Fact]
@@ -37,7 +36,7 @@ namespace WireMock.Net.Tests.Serialization
var model = _sut.Map((IMatcher[])null); var model = _sut.Map((IMatcher[])null);
// Assert // Assert
model.Should().BeNull(); Check.That(model).IsNull();
} }
[Fact] [Fact]
@@ -51,7 +50,7 @@ namespace WireMock.Net.Tests.Serialization
var models = _sut.Map(new[] { matcherMock1.Object, matcherMock2.Object }); var models = _sut.Map(new[] { matcherMock1.Object, matcherMock2.Object });
// Assert // Assert
models.Should().HaveCount(2); Check.That(models).HasSize(2);
} }
[Fact] [Fact]
@@ -66,10 +65,10 @@ namespace WireMock.Net.Tests.Serialization
var model = _sut.Map(matcherMock.Object); var model = _sut.Map(matcherMock.Object);
// Assert // Assert
model.IgnoreCase.Should().BeNull(); Check.That(model.IgnoreCase).IsNull();
model.Name.Should().Be("test"); Check.That(model.Name).Equals("test");
model.Pattern.Should().BeNull(); Check.That(model.Pattern).IsNull();
model.Patterns.Should().Contain("p1", "p2"); Check.That(model.Patterns).ContainsExactly("p1", "p2");
} }
[Fact] [Fact]
@@ -83,7 +82,7 @@ namespace WireMock.Net.Tests.Serialization
var model = _sut.Map(matcherMock.Object); var model = _sut.Map(matcherMock.Object);
// Assert // Assert
model.IgnoreCase.Should().BeTrue(); Check.That(model.IgnoreCase).Equals(true);
} }
[Fact] [Fact]
@@ -93,7 +92,7 @@ namespace WireMock.Net.Tests.Serialization
var result = _sut.Map((MatcherModel)null); var result = _sut.Map((MatcherModel)null);
// Assert // Assert
result.Should().BeNull(); Check.That(result).IsNull();
} }
[Fact] [Fact]
@@ -120,8 +119,8 @@ namespace WireMock.Net.Tests.Serialization
var matcher = (LinqMatcher)_sut.Map(model); var matcher = (LinqMatcher)_sut.Map(model);
// Assert // Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch); Check.That(matcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch);
matcher.GetPatterns().Should().Contain("p"); Check.That(matcher.GetPatterns()).ContainsExactly("p");
} }
[Fact] [Fact]
@@ -138,168 +137,8 @@ namespace WireMock.Net.Tests.Serialization
var matcher = (LinqMatcher)_sut.Map(model); var matcher = (LinqMatcher)_sut.Map(model);
// Assert // Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch); Check.That(matcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch);
matcher.GetPatterns().Should().Contain("p1", "p2"); Check.That(matcher.GetPatterns()).ContainsExactly("p1", "p2");
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonMatcher_Pattern_As_String()
{
// Assign
var pattern = "{ \"AccountIds\": [ 1, 2, 3 ] }";
var model = new MatcherModel
{
Name = "JsonMatcher",
Pattern = pattern
};
// Act
var matcher = (JsonMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(pattern);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonMatcher_Patterns_As_String()
{
// Assign
var pattern1 = "{ \"AccountIds\": [ 1, 2, 3 ] }";
var pattern2 = "{ \"X\": \"x\" }";
var patterns = new[] { pattern1, pattern2 };
var model = new MatcherModel
{
Name = "JsonMatcher",
Pattern = patterns
};
// Act
var matcher = (JsonMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(patterns);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonMatcher_Pattern_As_Object()
{
// Assign
var pattern = new { AccountIds = new[] { 1, 2, 3 } };
var model = new MatcherModel
{
Name = "JsonMatcher",
Pattern = pattern
};
// Act
var matcher = (JsonMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(pattern);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonMatcher_Patterns_As_Object()
{
// Assign
object pattern1 = new { AccountIds = new[] { 1, 2, 3 } };
object pattern2 = new { X = "x" };
var patterns = new[] { pattern1, pattern2 };
var model = new MatcherModel
{
Name = "JsonMatcher",
Patterns = patterns
};
// Act
var matcher = (JsonMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(patterns);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonPartialMatcher_Pattern_As_String()
{
// Assign
var pattern = "{ \"AccountIds\": [ 1, 2, 3 ] }";
var model = new MatcherModel
{
Name = "JsonPartialMatcher",
Pattern = pattern
};
// Act
var matcher = (JsonPartialMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(pattern);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonPartialMatcher_Patterns_As_String()
{
// Assign
var pattern1 = "{ \"AccountIds\": [ 1, 2, 3 ] }";
var pattern2 = "{ \"X\": \"x\" }";
var patterns = new[] { pattern1, pattern2 };
var model = new MatcherModel
{
Name = "JsonPartialMatcher",
Pattern = patterns
};
// Act
var matcher = (JsonPartialMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(patterns);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonPartialMatcher_Pattern_As_Object()
{
// Assign
var pattern = new { AccountIds = new[] { 1, 2, 3 } };
var model = new MatcherModel
{
Name = "JsonPartialMatcher",
Pattern = pattern
};
// Act
var matcher = (JsonPartialMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(pattern);
}
[Fact]
public void MatcherMapper_Map_MatcherModel_JsonPartialMatcher_Patterns_As_Object()
{
// Assign
object pattern1 = new { AccountIds = new[] { 1, 2, 3 } };
object pattern2 = new { X = "x" };
var patterns = new[] { pattern1, pattern2 };
var model = new MatcherModel
{
Name = "JsonPartialMatcher",
Patterns = patterns
};
// Act
var matcher = (JsonMatcher)_sut.Map(model);
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.Value.Should().BeEquivalentTo(patterns);
} }
} }
} }

View File

@@ -32,8 +32,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound); Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
server.Stop();
} }
[Fact] [Fact]
@@ -62,8 +60,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(responseNoState).Equals("No state msg"); Check.That(responseNoState).Equals("No state msg");
Check.That(responseWithState).Equals("Test state msg"); Check.That(responseWithState).Equals("Test state msg");
server.Stop();
} }
[Fact] [Fact]
@@ -98,8 +94,6 @@ namespace WireMock.Net.Tests
responseScenario1.Should().Be(body1); responseScenario1.Should().Be(body1);
responseScenario2.Should().Be(body1); responseScenario2.Should().Be(body1);
responseWithState.Should().Be(body2); responseWithState.Should().Be(body2);
server.Stop();
} }
[Fact] [Fact]
@@ -149,8 +143,6 @@ namespace WireMock.Net.Tests
t2a.Should().Be(body2); t2a.Should().Be(body2);
t2b.Should().Be(body2); t2b.Should().Be(body2);
t3.Should().Be(body3); t3.Should().Be(body3);
server.Stop();
} }
[Fact] [Fact]
@@ -179,8 +171,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(responseIntScenario).Equals("Scenario 1, Setting State 2"); Check.That(responseIntScenario).Equals("Scenario 1, Setting State 2");
Check.That(responseWithIntState).Equals("Scenario 1, State 2"); Check.That(responseWithIntState).Equals("Scenario 1, State 2");
server.Stop();
} }
[Fact] [Fact]
@@ -209,8 +199,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(responseIntScenario).Equals("string state, Setting State 2"); Check.That(responseIntScenario).Equals("string state, Setting State 2");
Check.That(responseWithIntState).Equals("string state, State 2"); Check.That(responseWithIntState).Equals("string state, State 2");
server.Stop();
} }
[Fact] [Fact]
@@ -239,8 +227,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(responseIntScenario).Equals("int state, Setting State 2"); Check.That(responseIntScenario).Equals("int state, Setting State 2");
Check.That(responseWithIntState).Equals("string state, State 2"); Check.That(responseWithIntState).Equals("string state, State 2");
server.Stop();
} }
[Fact] [Fact]
@@ -295,8 +281,6 @@ namespace WireMock.Net.Tests
Check.That(server.Scenarios["To do list"].NextState).IsNull(); Check.That(server.Scenarios["To do list"].NextState).IsNull();
Check.That(server.Scenarios["To do list"].Started).IsTrue(); Check.That(server.Scenarios["To do list"].Started).IsTrue();
Check.That(server.Scenarios["To do list"].Finished).IsTrue(); Check.That(server.Scenarios["To do list"].Finished).IsTrue();
server.Stop();
} }
[Fact] [Fact]
@@ -342,8 +326,6 @@ namespace WireMock.Net.Tests
var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo2X"); var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo2X");
Check.That(responseWithState2).Equals("Test state msg 2"); Check.That(responseWithState2).Equals("Test state msg 2");
server.Stop();
} }
} }
} }

View File

@@ -1,30 +0,0 @@
using System.Text;
using FluentAssertions;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.Util
{
public class BytesEncodingUtilsTests
{
[Fact]
public void TryGetEncoding_UTF32()
{
var result = BytesEncodingUtils.TryGetEncoding(new byte[] { 0xff, 0xfe, 0x00, 0x00 }, out Encoding encoding);
// Assert
result.Should().BeTrue();
encoding.CodePage.Should().Be(Encoding.UTF32.CodePage);
}
[Fact]
public void TryGetEncoding_Invalid()
{
var result = BytesEncodingUtils.TryGetEncoding(new byte[] { 0xff }, out Encoding encoding);
// Assert
result.Should().BeFalse();
encoding.Should().BeNull();
}
}
}

View File

@@ -1,4 +1,3 @@
using FluentAssertions;
using NFluent; using NFluent;
using WireMock.Util; using WireMock.Util;
using Xunit; using Xunit;
@@ -14,14 +13,13 @@ namespace WireMock.Net.Tests.Util
string url = "test"; string url = "test";
// Act // Act
bool result = PortUtils.TryExtract(url, out bool isHttps, out string proto, out string host, out int port); bool result = PortUtils.TryExtract(url, out string proto, out string host, out int port);
// Assert // Assert
result.Should().BeFalse(); Check.That(result).IsFalse();
isHttps.Should().BeFalse(); Check.That(proto).IsNull();
proto.Should().BeNull(); Check.That(host).IsNull();
host.Should().BeNull(); Check.That(port).IsEqualTo(default(int));
port.Should().Be(default(int));
} }
[Fact] [Fact]
@@ -31,58 +29,39 @@ namespace WireMock.Net.Tests.Util
string url = "http://0.0.0.0"; string url = "http://0.0.0.0";
// Act // Act
bool result = PortUtils.TryExtract(url, out bool isHttps, out string proto, out string host, out int port); bool result = PortUtils.TryExtract(url, out string proto, out string host, out int port);
// Assert // Assert
result.Should().BeFalse(); Check.That(result).IsFalse();
isHttps.Should().BeFalse(); Check.That(proto).IsNull();
proto.Should().BeNull(); Check.That(host).IsNull();
host.Should().BeNull(); Check.That(port).IsEqualTo(default(int));
port.Should().Be(default(int));
} }
[Fact] [Fact]
public void PortUtils_TryExtract_Http_Returns_True() public void PortUtils_TryExtract_ValidUrl1_Returns_True()
{
// Assign
string url = "http://wiremock.net:1234";
// Act
bool result = PortUtils.TryExtract(url, out bool isHttps, out string proto, out string host, out int port);
// Assert
result.Should().BeTrue();
isHttps.Should().BeFalse();
proto.Should().Be("http");
host.Should().Be("wiremock.net");
port.Should().Be(1234);
}
[Fact]
public void PortUtils_TryExtract_Https_Returns_True()
{ {
// Assign // Assign
string url = "https://wiremock.net:5000"; string url = "https://wiremock.net:5000";
// Act // Act
bool result = PortUtils.TryExtract(url, out bool isHttps, out string proto, out string host, out int port); bool result = PortUtils.TryExtract(url, out string proto, out string host, out int port);
// Assert // Assert
result.Should().BeTrue(); Check.That(result).IsTrue();
isHttps.Should().BeTrue(); Check.That(proto).IsEqualTo("https");
proto.Should().Be("https"); Check.That(host).IsEqualTo("wiremock.net");
host.Should().Be("wiremock.net"); Check.That(port).IsEqualTo(5000);
port.Should().Be(5000);
} }
[Fact] [Fact]
public void PortUtils_TryExtract_Https0_0_0_0_Returns_True() public void PortUtils_TryExtract_ValidUrl2_Returns_True()
{ {
// Assign // Assign
string url = "https://0.0.0.0:5000"; string url = "https://0.0.0.0:5000";
// Act // Act
bool result = PortUtils.TryExtract(url, out bool isHttps, out string proto, out string host, out int port); bool result = PortUtils.TryExtract(url, out string proto, out string host, out int port);
// Assert // Assert
Check.That(result).IsTrue(); Check.That(result).IsTrue();

View File

@@ -2,16 +2,18 @@
<PropertyGroup> <PropertyGroup>
<Authors>Stef Heyenrath</Authors> <Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;netcoreapp3.1;net5.0</TargetFrameworks> <!--<TargetFrameworks>net452;netcoreapp2.1</TargetFrameworks>-->
<IsPackable>false</IsPackable> <TargetFramework>netcoreapp3.1</TargetFramework>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<AssemblyName>WireMock.Net.Tests</AssemblyName> <AssemblyName>WireMock.Net.Tests</AssemblyName>
<PackageId>WireMock.Net.Tests</PackageId> <PackageId>WireMock.Net.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
<ProjectGuid>{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}</ProjectGuid> <ProjectGuid>{31DC2EF8-C3FE-467D-84BE-FB5D956E612E}</ProjectGuid>
<!--<SonarQubeTestProject>True</SonarQubeTestProject> <!-- https://github.com/tonerdo/coverlet/issues/6 -->
<SonarQubeExclude>True</SonarQubeExclude>--> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<SonarQubeTestProject>True</SonarQubeTestProject>
<SonarQubeExclude>True</SonarQubeExclude>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>../../src/WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>../../src/WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
@@ -23,6 +25,9 @@
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
</PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.FluentAssertions\WireMock.Net.FluentAssertions.csproj" /> <ProjectReference Include="..\..\src\WireMock.Net.FluentAssertions\WireMock.Net.FluentAssertions.csproj" />
@@ -32,33 +37,27 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Codecov" Version="1.10.0" /> <PackageReference Include="Codecov" Version="1.10.0" />
<PackageReference Include="coverlet.msbuild" Version="3.0.0-preview.9"> <PackageReference Include="coverlet.msbuild" Version="2.8.1">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.0.0-preview.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="5.10.3" /> <PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="System.Threading" Version="4.3.0" /> <PackageReference Include="System.Threading" Version="4.3.0" />
<PackageReference Include="RestEase" Version="1.4.10" /> <PackageReference Include="RestEase" Version="1.4.10" />
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" /> <PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Moq" Version="4.14.5" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NFluent" Version="2.7.0" /> <PackageReference Include="NFluent" Version="2.7.0" />
<!--<PackageReference Include="OpenCover" Version="4.7.922" />--> <PackageReference Include="OpenCover" Version="4.7.922" />
<!--<PackageReference Include="ReportGenerator" Version="4.8.1" />--> <PackageReference Include="ReportGenerator" Version="4.6.7" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" /> <PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.12" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<!--<PackageReference Include="StrongNamer" Version="0.0.8" />--> <!--<PackageReference Include="StrongNamer" Version="0.0.8" />-->
</ItemGroup> </ItemGroup>
@@ -67,6 +66,10 @@
<PackageReference Include="System.ValueTuple" Version="4.5.0" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.4" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="responsebody.json"> <None Update="responsebody.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

View File

@@ -31,6 +31,16 @@ namespace WireMock.Net.Tests
return current; return current;
} }
[Fact]
public void WireMockServer_Admin_StartStop()
{
var server1 = WireMockServer.Start("http://localhost:19091");
Check.That(server1.Urls[0]).Equals("http://localhost:19091");
server1.Stop();
}
[Fact] [Fact]
public void WireMockServer_Admin_ResetMappings() public void WireMockServer_Admin_ResetMappings()
{ {
@@ -47,8 +57,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(server.Mappings).HasSize(0); Check.That(server.Mappings).HasSize(0);
Check.That(server.MappingModels).HasSize(0); Check.That(server.MappingModels).HasSize(0);
server.Stop();
} }
[Fact] [Fact]
@@ -98,8 +106,6 @@ namespace WireMock.Net.Tests
Check.That(mappings.First().Provider).IsNotNull(); Check.That(mappings.First().Provider).IsNotNull();
Check.That(mappings.First().Guid).Equals(guid); Check.That(mappings.First().Guid).Equals(guid);
Check.That(mappings.First().Title).Equals(title); Check.That(mappings.First().Title).Equals(title);
server.Stop();
} }
[Fact] [Fact]
@@ -118,8 +124,6 @@ namespace WireMock.Net.Tests
Check.That(mappings.First().Provider).IsNotNull(); Check.That(mappings.First().Provider).IsNotNull();
Check.That(mappings.First().Guid).Equals(Guid.Parse(guid)); Check.That(mappings.First().Guid).Equals(Guid.Parse(guid));
Check.That(mappings.First().Title).IsNullOrEmpty(); Check.That(mappings.First().Title).IsNullOrEmpty();
server.Stop();
} }
[Fact] [Fact]
@@ -132,8 +136,6 @@ namespace WireMock.Net.Tests
var mappings = server.Mappings.ToArray(); var mappings = server.Mappings.ToArray();
Check.That(mappings).HasSize(2); Check.That(mappings).HasSize(2);
server.Stop();
} }
[Fact] [Fact]
@@ -162,8 +164,6 @@ namespace WireMock.Net.Tests
Check.That(mappings.First().Provider).IsNotNull(); Check.That(mappings.First().Provider).IsNotNull();
Check.That(mappings.First().Guid).Equals(Guid.Parse(guid)); Check.That(mappings.First().Guid).Equals(Guid.Parse(guid));
Check.That(mappings.First().Title).IsNullOrEmpty(); Check.That(mappings.First().Title).IsNullOrEmpty();
server.Stop();
} }
[Fact] [Fact]
@@ -219,8 +219,6 @@ namespace WireMock.Net.Tests
var mappings = server.Mappings.ToArray(); var mappings = server.Mappings.ToArray();
Check.That(mappings).HasSize(6); Check.That(mappings).HasSize(6);
server.Stop();
} }
[Fact] [Fact]
@@ -259,8 +257,6 @@ namespace WireMock.Net.Tests
var mappings = server.Mappings.ToArray(); var mappings = server.Mappings.ToArray();
Check.That(mappings).HasSize(2); Check.That(mappings).HasSize(2);
server.Stop();
} }
[Fact] [Fact]
@@ -274,8 +270,6 @@ namespace WireMock.Net.Tests
var mappings = server.Mappings.ToArray(); var mappings = server.Mappings.ToArray();
Check.That(mappings).HasSize(1); Check.That(mappings).HasSize(1);
server.Stop();
} }
[Fact] [Fact]
@@ -302,8 +296,6 @@ namespace WireMock.Net.Tests
Check.That(mappings2).HasSize(1); Check.That(mappings2).HasSize(1);
Check.That(mappings2.First().Guid).Equals(guid); Check.That(mappings2.First().Guid).Equals(guid);
Check.That(mappings2.First().Provider).Equals(response2); Check.That(mappings2.First().Provider).Equals(response2);
server.Stop();
} }
[Fact] [Fact]
@@ -328,8 +320,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That((int)response.StatusCode).IsEqualTo(400); Check.That((int)response.StatusCode).IsEqualTo(400);
server.Stop();
} }
[Fact] [Fact]
@@ -346,8 +336,6 @@ namespace WireMock.Net.Tests
var requestLogged = server.LogEntries.First(); var requestLogged = server.LogEntries.First();
Check.That(requestLogged.RequestMessage.Method).IsEqualTo("GET"); Check.That(requestLogged.RequestMessage.Method).IsEqualTo("GET");
Check.That(requestLogged.RequestMessage.BodyData).IsNull(); Check.That(requestLogged.RequestMessage.BodyData).IsNull();
server.Stop();
} }
[Fact] [Fact]
@@ -371,8 +359,6 @@ namespace WireMock.Net.Tests
var requestLoggedB = server.LogEntries.Last(); var requestLoggedB = server.LogEntries.Last();
Check.That(requestLoggedB.RequestMessage.Path).EndsWith("/foo3"); Check.That(requestLoggedB.RequestMessage.Path).EndsWith("/foo3");
server.Stop();
} }
[Fact] [Fact]

View File

@@ -22,8 +22,6 @@ namespace WireMock.Net.Tests
Check.That(options.AuthorizationMatcher.Name).IsEqualTo("RegexMatcher"); Check.That(options.AuthorizationMatcher.Name).IsEqualTo("RegexMatcher");
Check.That(options.AuthorizationMatcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch); Check.That(options.AuthorizationMatcher.MatchBehaviour).IsEqualTo(MatchBehaviour.AcceptOnMatch);
Check.That(options.AuthorizationMatcher.GetPatterns()).ContainsExactly("^(?i)BASIC eDp5$"); Check.That(options.AuthorizationMatcher.GetPatterns()).ContainsExactly("^(?i)BASIC eDp5$");
server.Stop();
} }
[Fact] [Fact]
@@ -39,8 +37,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthorizationMatcher).IsNull(); Check.That(options.AuthorizationMatcher).IsNull();
server.Stop();
} }
} }
} }

View File

@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using NFluent; using NFluent;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Logging;
using WireMock.Matchers.Request; using WireMock.Matchers.Request;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
using WireMock.ResponseBuilders; using WireMock.ResponseBuilders;
@@ -19,37 +20,6 @@ namespace WireMock.Net.Tests
{ {
public class WireMockServerProxyTests public class WireMockServerProxyTests
{ {
[Fact(Skip = "Fails in Linux CI")]
public async Task WireMockServer_ProxySSL_Should_log_proxied_requests()
{
// Assign
var settings = new WireMockServerSettings
{
UseSSL = true,
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = "https://www.google.com",
SaveMapping = true,
SaveMappingToFile = false
}
};
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 };
await new HttpClient(httpClientHandler).SendAsync(requestMessage);
// Assert
Check.That(server.Mappings).HasSize(2);
Check.That(server.LogEntries).HasSize(1);
}
[Fact] [Fact]
public async Task WireMockServer_Proxy_Should_log_proxied_requests() public async Task WireMockServer_Proxy_Should_log_proxied_requests()
{ {
@@ -103,8 +73,6 @@ namespace WireMock.Net.Tests
Check.That(server.Mappings).HasSize(1); Check.That(server.Mappings).HasSize(1);
Check.That(server.LogEntries).HasSize(1); Check.That(server.LogEntries).HasSize(1);
Check.That(content).Contains("google"); Check.That(content).Contains("google");
server.Stop();
} }
[Fact] [Fact]
@@ -518,8 +486,6 @@ namespace WireMock.Net.Tests
Check.That(content2).IsEqualTo("[]"); Check.That(content2).IsEqualTo("[]");
} }
// On Ubuntu latest it's : "Resource temporarily unavailable"
// On Windows-2019 it's : "No such host is known."
[Fact] [Fact]
public async Task WireMockServer_Proxy_WhenTargetIsNotAvailable_Should_Return_CorrectResponse() public async Task WireMockServer_Proxy_WhenTargetIsNotAvailable_Should_Return_CorrectResponse()
{ {
@@ -546,12 +512,10 @@ namespace WireMock.Net.Tests
result.StatusCode.Should().Be(500); result.StatusCode.Should().Be(500);
var content = await result.Content.ReadAsStringAsync(); var content = await result.Content.ReadAsStringAsync();
content.Should().NotBeEmpty(); 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); server.LogEntries.Should().HaveCount(1);
var status = ((StatusModel)server.LogEntries.First().ResponseMessage.BodyData.BodyAsJson).Status; ((StatusModel)server.LogEntries.First().ResponseMessage.BodyData.BodyAsJson).Status.Should().Contain("known");
server.Stop();
} }
} }
} }

View File

@@ -1,39 +0,0 @@
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using Xunit;
namespace WireMock.Net.Tests
{
public partial class WireMockServerTests
{
[Theory]
[InlineData(HttpStatusCode.Conflict)]
[InlineData(409)]
[InlineData("409")]
public async Task WireMockServer_WithCallback_Should_Use_StatusCodeFromResponse(object statusCode)
{
// Arrange
var server = WireMockServer.Start();
server.Given(Request.Create().UsingPost().WithPath("/foo"))
.RespondWith(Response.Create()
.WithCallback(request => new ResponseMessage
{
StatusCode = statusCode
}));
// Act
var httpClient = new HttpClient();
var response = await httpClient.PostAsync("http://localhost:" + server.Ports[0] + "/foo", new StringContent("dummy"));
// Assert
response.StatusCode.Should().Be(409);
server.Stop();
}
}
}

View File

@@ -15,7 +15,7 @@ using Xunit;
namespace WireMock.Net.Tests namespace WireMock.Net.Tests
{ {
public partial class WireMockServerTests public class WireMockServerTests
{ {
[Fact] [Fact]
public async Task WireMockServer_Should_reset_requestlogs() public async Task WireMockServer_Should_reset_requestlogs()
@@ -29,8 +29,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(server.LogEntries).IsEmpty(); Check.That(server.LogEntries).IsEmpty();
server.Stop();
} }
[Fact] [Fact]
@@ -53,8 +51,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(server.Mappings).IsEmpty(); Check.That(server.Mappings).IsEmpty();
Check.ThatAsyncCode(() => new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path)).ThrowsAny(); Check.ThatAsyncCode(() => new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path)).ThrowsAny();
server.Stop();
} }
[Fact] [Fact]
@@ -86,8 +82,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(response).IsEqualTo("REDIRECT SUCCESSFUL"); Check.That(response).IsEqualTo("REDIRECT SUCCESSFUL");
server.Stop();
} }
[Fact] [Fact]
@@ -111,8 +105,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200); Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200);
server.Stop();
} }
[Fact] [Fact]
@@ -133,8 +125,6 @@ namespace WireMock.Net.Tests
// then // then
Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200); Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200);
server.Stop();
} }
//Leaving commented as this requires an actual certificate with password, along with a service that expects a client certificate //Leaving commented as this requires an actual certificate with password, along with a service that expects a client certificate
@@ -171,8 +161,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(response.Headers.Contains("test")).IsTrue(); Check.That(response.Headers.Contains("test")).IsTrue();
Check.That(response.Headers.Contains("Transfer-Encoding")).IsFalse(); Check.That(response.Headers.Contains("Transfer-Encoding")).IsFalse();
server.Stop();
} }
#if !NET452 #if !NET452
@@ -201,8 +189,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(response.StatusCode).Equals(HttpStatusCode.OK); Check.That(response.StatusCode).Equals(HttpStatusCode.OK);
server.Stop();
} }
#endif #endif
@@ -235,8 +221,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(response.StatusCode).Equals(HttpStatusCode.OK); Check.That(response.StatusCode).Equals(HttpStatusCode.OK);
server.Stop();
} }
[Theory] [Theory]
@@ -270,8 +254,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(response.StatusCode).Equals(HttpStatusCode.Created); Check.That(response.StatusCode).Equals(HttpStatusCode.Created);
Check.That(await response.Content.ReadAsStringAsync()).Contains("Mapping added"); Check.That(await response.Content.ReadAsStringAsync()).Contains("Mapping added");
server.Stop();
} }
[Theory] [Theory]
@@ -302,8 +284,6 @@ namespace WireMock.Net.Tests
// Assert // Assert
Check.That(await response.Content.ReadAsStringAsync()).Contains("OK"); Check.That(await response.Content.ReadAsStringAsync()).Contains("OK");
server.Stop();
} }
} }
} }

View File

@@ -51,8 +51,6 @@ namespace WireMock.Net.Tests.WithMapping
m.Response.Body == response && m.Response.Body == response &&
(int)m.Response.StatusCode == 201 (int)m.Response.StatusCode == 201
); );
server.Stop();
} }
[Fact] [Fact]
@@ -88,8 +86,6 @@ namespace WireMock.Net.Tests.WithMapping
m.Guid == Guid.Parse("532889c2-f84d-4dc8-b847-9ea2c6aca7d5") && m.Guid == Guid.Parse("532889c2-f84d-4dc8-b847-9ea2c6aca7d5") &&
(int)m.Response.StatusCode == 201 (int)m.Response.StatusCode == 201
); );
server.Stop();
} }
[Fact] [Fact]
@@ -124,8 +120,6 @@ namespace WireMock.Net.Tests.WithMapping
// Assert // Assert
server.MappingModels.Should().HaveCount(2); server.MappingModels.Should().HaveCount(2);
server.Stop();
} }
} }
} }