diff --git a/README.md b/README.md
index 14c771e2..bff39aa0 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,8 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w
| **Issues** | [](https://github.com/WireMock-Net/WireMock.Net/issues) |
| | |
| ***Quality*** | |
-| **Build** | [](https://ci.appveyor.com/project/StefH/wiremock-net) |
+| **Build AppVeyor** | [](https://ci.appveyor.com/project/StefH/wiremock-net) |
+| **Build Azure** | [](https://stef.visualstudio.com/WireMock.Net/_build/latest?definitionId=7) |
| **CodeFactor** | [](https://www.codefactor.io/repository/github/wiremock-net/wiremock.net)
| **Sonar Quality Gate** | [](https://sonarcloud.io/project/issues?id=wiremock) |
| **Sonar Bugs** | [](https://sonarcloud.io/project/issues?id=wiremock&resolved=false&types=BUG) |
diff --git a/WireMock.Net Solution.sln b/WireMock.Net Solution.sln
index 429b675f..8c5eade3 100644
--- a/WireMock.Net Solution.sln
+++ b/WireMock.Net Solution.sln
@@ -9,11 +9,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
.runsettings = .runsettings
appveyor.yml = appveyor.yml
+ azure-pipelines-linux.yml = azure-pipelines-linux.yml
+ azure-pipelines.yml = azure-pipelines.yml
CHANGELOG.md = CHANGELOG.md
- codecov-local.cmd = codecov-local.cmd
GitReleaseNotes.txt = GitReleaseNotes.txt
README.md = README.md
ReSharper_WireMock.DotSettings = ReSharper_WireMock.DotSettings
+ report\run-codecov-local.cmd = report\run-codecov-local.cmd
+ report\run-coverlet-local.cmd = report\run-coverlet-local.cmd
WireMock.Net Solution.sln.DotSettings = WireMock.Net Solution.sln.DotSettings
EndProjectSection
EndProject
diff --git a/appveyor.yml b/appveyor.yml
index fe97a9fd..0d9c49ac 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -34,7 +34,7 @@ before_build:
build_script:
# Begin SonarScanner
-- ps: 'if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { & dotnet sonarscanner begin /k:"wiremock" /d:sonar.organization="stefh-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env:SONAR_TOKEN" /v:"$env:APPVEYOR_BUILD_NUMBER" /d:sonar.cs.opencover.reportsPaths="$env:CD\coverage.xml" }'
+# - ps: 'if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { & dotnet sonarscanner begin /k:"wiremock" /d:sonar.organization="stefh-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$env:SONAR_TOKEN" /v:"$env:APPVEYOR_BUILD_NUMBER" /d:sonar.cs.opencover.reportsPaths="$env:CD\coverage.xml" }'
# build WireMock.Net
- dotnet build .\src\WireMock.Net\WireMock.Net.csproj -c %CONFIGURATION%
@@ -57,4 +57,4 @@ test_script:
# End SonarScanner
-- ps: 'if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { & dotnet sonarscanner end /d:sonar.login="$env:SONAR_TOKEN" }'
\ No newline at end of file
+# - ps: 'if (-Not $env:APPVEYOR_PULL_REQUEST_NUMBER) { & dotnet sonarscanner end /d:sonar.login="$env:SONAR_TOKEN" }'
\ No newline at end of file
diff --git a/azure-pipelines-linux.yml b/azure-pipelines-linux.yml
new file mode 100644
index 00000000..1713472f
--- /dev/null
+++ b/azure-pipelines-linux.yml
@@ -0,0 +1,13 @@
+pool:
+ vmImage: 'Ubuntu 16.04'
+
+variables:
+ buildConfiguration: 'Release'
+
+steps:
+- script: |
+ dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx
+- task: PublishTestResults@2
+ inputs:
+ testRunner: VSTest
+ testResultsFiles: '**/*.trx'
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
new file mode 100644
index 00000000..d4b5702a
--- /dev/null
+++ b/azure-pipelines.yml
@@ -0,0 +1,37 @@
+pool:
+ vmImage: 'vs2017-win2016'
+
+variables:
+ buildConfiguration: 'Debug'
+ buildId: "1$(Build.BuildId)"
+
+steps:
+# Print buildId
+- script: |
+ echo "BuildId = $(buildId)"
+
+# Install SonarScanner
+- script: |
+ dotnet tool install --global dotnet-sonarscanner
+
+# Begin SonarScanner
+# See also
+# - 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.`
+# - https://github.com/dotnet/cli/issues/8368
+# - https://github.com/Microsoft/vsts-tasks/issues/8291
+#
+- script: |
+ %USERPROFILE%\.dotnet\tools\dotnet-sonarscanner begin /k:"wiremock" /d:sonar.organization="stefh-github" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.login="$(SONAR_TOKEN)" /v:"$(buildId)" /d:sonar.cs.opencover.reportsPaths="**\coverage.opencover.xml"
+
+# Build source, tests and run tests
+- script: |
+ dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration $(buildConfiguration) --framework netcoreapp2.1 --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
+
+# End SonarScanner
+- script: |
+ %USERPROFILE%\.dotnet\tools\dotnet-sonarscanner end /d:sonar.login="$(SONAR_TOKEN)"
+
+- task: PublishTestResults@2
+ inputs:
+ testRunner: VSTest
+ testResultsFiles: '**/*.trx'
\ No newline at end of file
diff --git a/codecov-local.cmd b/codecov-local.cmd
deleted file mode 100644
index 9b0261ad..00000000
--- a/codecov-local.cmd
+++ /dev/null
@@ -1,9 +0,0 @@
-rem https://www.appveyor.com/blog/2017/03/17/codecov/
-
-dotnet build .\test\WireMock.Net.Tests\WireMock.Net.Tests.csproj -c Debug
-
-%USERPROFILE%\.nuget\packages\opencover\4.6.519\tools\OpenCover.Console.exe -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -output:coverage.xml -register:user -oldStyle -searchdirs:"test\WireMock.Net.Tests\bin\debug\net452"
-
-%USERPROFILE%\.nuget\packages\ReportGenerator\2.5.6\tools\ReportGenerator.exe -reports:"coverage.xml" -targetdir:"report"
-
-start report\index.htm
\ No newline at end of file
diff --git a/coverage.xml b/coverage.xml
deleted file mode 100644
index 572e0233..00000000
--- a/coverage.xml
+++ /dev/null
@@ -1,43959 +0,0 @@
-
-
| Class: | WireMock.ResponseBuilders.BodyDestinationFormat |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | |
| Covered lines: | 0 |
| Uncovered lines: | 0 |
| Coverable lines: | 0 |
| Total lines: | 0 |
| Line coverage: |
No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).
-| Class: | WireMock.Util.BodyParser |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\BodyParser.cs |
| Covered lines: | 42 |
| Uncovered lines: | 8 |
| Coverable lines: | 50 |
| Total lines: | 81 |
| Line coverage: | 84% |
| Branch coverage: | 83.3% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .cctor() | 1 | 0 | 100 | 100 |
| ReadStringAsync() | 6 | 2 | 100 | 100 |
| ReadBytesAsync() | 6 | 2 | 100 | 66.67 |
| Parse() | 16 | 16 | 79.31 | 88.89 |
| Class: | WireMock.Matchers.ExactMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\ExactMatcher.cs |
| Covered lines: | 14 |
| Uncovered lines: | 0 |
| Coverable lines: | 14 |
| Total lines: | 44 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 1 | 0 | 100 | 100 |
| IsMatch(...) | 1 | 0 | 100 | 100 |
| GetPatterns() | 1 | 0 | 100 | 100 |
| GetName() | 1 | 0 | 100 | 100 |
| Class: | WireMock.Matchers.ExactObjectMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\ExactObjectMatcher.cs |
| Covered lines: | 15 |
| Uncovered lines: | 0 |
| Coverable lines: | 15 |
| Total lines: | 46 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 1 | 0 | 100 | 100 |
| .ctor(...) | 1 | 0 | 100 | 100 |
| IsMatch(...) | 2 | 0 | 100 | 100 |
| GetName() | 1 | 0 | 100 | 100 |
| Class: | WireMock.Util.FileHelper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\FileHelper.cs |
| Covered lines: | 6 |
| Uncovered lines: | 6 |
| Coverable lines: | 12 |
| Total lines: | 29 |
| Line coverage: | 50% |
| Branch coverage: | 50% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| ReadAllText(...) | 2 | 2 | 50 | 66.67 |
| Class: | WireMock.Admin.Mappings.HeaderModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\HeaderModel.cs |
| Covered lines: | 0 |
| Uncovered lines: | 3 |
| Coverable lines: | 3 |
| Total lines: | 34 |
| Line coverage: | 0% |
| Class: | WireMock.Http.HttpKnownHeaderNames |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | |
| Covered lines: | 0 |
| Uncovered lines: | 0 |
| Coverable lines: | 0 |
| Total lines: | 0 |
| Line coverage: |
No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).
-| Class: | WireMock.HttpListenerRequestMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\Stef\Documents\GitHub\WireMock.Net\src\WireMock.Net\HttpListenerRequestMapper.cs |
| Covered lines: | 23 |
| Uncovered lines: | 1 |
| Coverable lines: | 24 |
| Total lines: | 60 |
| Line coverage: | 95.8% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Map(...) | 8 | 4 | 87.5 | 100 |
| GetRequestBody(...) | 4 | 2 | 100 | 100 |
| Class: | WireMock.HttpListenerResponseMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\Stef\Documents\GitHub\WireMock.Net\src\WireMock.Net\HttpListenerResponseMapper.cs |
| Covered lines: | 13 |
| Uncovered lines: | 0 |
| Coverable lines: | 13 |
| Total lines: | 39 |
| Line coverage: | 100% |
| Branch coverage: | 75% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Map(...) | 3 | 4 | 100 | 80 |
| .ctor() | 1 | 0 | 100 | 100 |
| Class: | WireMock.Http.HttpResponseMessageHelper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Http\HttpResponseMessageHelper.cs |
| Covered lines: | 31 |
| Uncovered lines: | 0 |
| Coverable lines: | 31 |
| Total lines: | 53 |
| Line coverage: | 100% |
| Branch coverage: | 75% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Create() | 18 | 64 | 100 | 76.92 |
| Class: | WireMock.Matchers.JsonPathMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\JsonPathMatcher.cs |
| Covered lines: | 23 |
| Uncovered lines: | 10 |
| Coverable lines: | 33 |
| Total lines: | 88 |
| Line coverage: | 69.6% |
| Branch coverage: | 50% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 1 | 0 | 100 | 100 |
| IsMatch(...) | 2 | 2 | 54.55 | 66.67 |
| IsMatch(...) | 3 | 4 | 54.55 | 60 |
| GetPatterns() | 1 | 0 | 100 | 100 |
| GetName() | 1 | 0 | 100 | 100 |
| Class: | WireMock.Util.JsonUtils |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\JsonUtils.cs |
| Covered lines: | 5 |
| Uncovered lines: | 2 |
| Coverable lines: | 7 |
| Total lines: | 18 |
| Line coverage: | 71.4% |
| Branch coverage: | 50% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| ParseJTokenToObject(...) | 3 | 4 | 71.43 | 60 |
| Class: | WireMock.Serialization.MappingConverter |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Serialization\MappingConverter.cs |
| Covered lines: | 103 |
| Uncovered lines: | 25 |
| Coverable lines: | 128 |
| Total lines: | 162 |
| Line coverage: | 80.4% |
| Branch coverage: | 41.6% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| ToMappingModel(...) | 51 | 524288 | 69.77 | 51.28 |
| Map(...) | 5 | 4 | 53.33 | 40 |
| Map(...) | 4 | 2 | 0 | 0 |
| Map(...) | 3 | 2 | 0 | 0 |
| Class: | WireMock.Serialization.MatcherMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Serialization\MatcherMapper.cs |
| Covered lines: | 17 |
| Uncovered lines: | 0 |
| Coverable lines: | 17 |
| Total lines: | 35 |
| Line coverage: | 100% |
| Branch coverage: | 90% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Map(...) | 4 | 2 | 100 | 100 |
| Map(...) | 9 | 16 | 100 | 88.89 |
| Class: | WireMock.Serialization.MatcherModelMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Serialization\MatcherModelMapper.cs |
| Covered lines: | 19 |
| Uncovered lines: | 2 |
| Coverable lines: | 21 |
| Total lines: | 55 |
| Line coverage: | 90.4% |
| Branch coverage: | 86.3% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Map(...) | 17 | 2048 | 90.48 | 86.96 |
| Class: | WireMock.Owin.OwinResponseMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Owin\OwinResponseMapper.cs |
| Covered lines: | 44 |
| Uncovered lines: | 4 |
| Coverable lines: | 48 |
| Total lines: | 105 |
| Line coverage: | 91.6% |
| Branch coverage: | 81.2% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor() | 1 | 0 | 100 | 100 |
| .cctor() | 1 | 0 | 100 | 100 |
| MapAsync() | 30 | 256 | 90 | 82.35 |
| Class: | WireMock.Owin.OwinSelfHost |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Owin\OwinSelfHost.cs |
| Covered lines: | 51 |
| Uncovered lines: | 0 |
| Coverable lines: | 51 |
| Total lines: | 96 |
| Line coverage: | 100% |
| Branch coverage: | 66.6% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 2 | 0 | 100 | 100 |
| StartAsync() | 1 | 0 | 100 | 100 |
| StopAsync() | 1 | 0 | 100 | 100 |
| StartServers() | 4 | 2 | 100 | 100 |
| Class: | WireMock.Admin.Mappings.ParamModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\ParamModel.cs |
| Covered lines: | 0 |
| Uncovered lines: | 3 |
| Coverable lines: | 3 |
| Total lines: | 34 |
| Line coverage: | 0% |
| Class: | WireMock.Matchers.RegexMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\RegexMatcher.cs |
| Covered lines: | 28 |
| Uncovered lines: | 4 |
| Coverable lines: | 32 |
| Total lines: | 81 |
| Line coverage: | 87.5% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 1 | 0 | 100 | 100 |
| .ctor(...) | 2 | 2 | 100 | 100 |
| IsMatch(...) | 2 | 2 | 70 | 100 |
| GetPatterns() | 1 | 0 | 100 | 100 |
| GetName() | 1 | 0 | 100 | 100 |
| Class: | WireMock.RegistrationCallback |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | |
| Covered lines: | 0 |
| Uncovered lines: | 0 |
| Coverable lines: | 0 |
| Total lines: | 0 |
| Line coverage: |
No files found. This usually happens if a file isn't covered by a test or the class does not contain any sequence points (e.g. a class that only contains auto properties).
-| Class: | WireMock.Transformers.ResponseMessageTransformer |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Transformers\ResponseMessageTransformer.cs |
| Covered lines: | 33 |
| Uncovered lines: | 0 |
| Coverable lines: | 33 |
| Total lines: | 57 |
| Line coverage: | 100% |
| Branch coverage: | 87.5% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Transform(...) | 8 | 16 | 100 | 88.89 |
| Class: | WireMock.Http.TinyHttpServer |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\Stef\Documents\GitHub\WireMock.Net\src\WireMock.Net\Http\TinyHttpServer.cs |
| Covered lines: | 42 |
| Uncovered lines: | 0 |
| Coverable lines: | 42 |
| Total lines: | 113 |
| Line coverage: | 100% |
| Branch coverage: | 50% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 2 | 0 | 100 | 100 |
| Start() | 1 | 0 | 100 | 100 |
| Stop() | 2 | 2 | 100 | 66.67 |
| <Start() | 4 | 2 | 77.78 | 66.67 |
| Class: | WireMock.Matchers.WildcardMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\WildcardMatcher.cs |
| Covered lines: | 13 |
| Uncovered lines: | 0 |
| Coverable lines: | 13 |
| Total lines: | 46 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 1 | 0 | 100 | 100 |
| .ctor(...) | 2 | 0 | 100 | 100 |
| GetPatterns() | 1 | 0 | 100 | 100 |
| GetName() | 1 | 0 | 100 | 100 |
| Class: | WireMock.Logging.WireMockConsoleLogger |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Logging\WireMockConsoleLogger.cs |
| Covered lines: | 0 |
| Uncovered lines: | 16 |
| Coverable lines: | 16 |
| Total lines: | 42 |
| Line coverage: | 0% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Debug(...) | 1 | 0 | 0 | 0 |
| Info(...) | 1 | 0 | 0 | 0 |
| Warn(...) | 1 | 0 | 0 | 0 |
| Error(...) | 1 | 0 | 0 | 0 |
| Format(...) | 1 | 0 | 0 | 0 |
| Class: | WireMock.Logging.WireMockNullLogger |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Logging\WireMockNullLogger.cs |
| Covered lines: | 6 |
| Uncovered lines: | 2 |
| Coverable lines: | 8 |
| Total lines: | 29 |
| Line coverage: | 75% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Debug(...) | 1 | 0 | 100 | 100 |
| Info(...) | 1 | 0 | 100 | 100 |
| Warn(...) | 1 | 0 | 100 | 100 |
| Error(...) | 1 | 0 | 0 | 0 |
| Class: | WireMock.Net.StandAlone.SimpleCommandLineParser |
|---|---|
| Assembly: | WireMock.Net.StandAlone |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net.StandAlone\SimpleCommandLineParser.cs |
| Covered lines: | 0 |
| Uncovered lines: | 54 |
| Coverable lines: | 54 |
| Total lines: | 83 |
| Line coverage: | 0% |
| Branch coverage: | 0% |
| Class: | WireMock.Net.StandAlone.StandAloneApp |
|---|---|
| Assembly: | WireMock.Net.StandAlone |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net.StandAlone\StandAloneApp.cs |
| Covered lines: | 0 |
| Uncovered lines: | 48 |
| Coverable lines: | 48 |
| Total lines: | 90 |
| Line coverage: | 0% |
| Branch coverage: | 0% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Start(...) | 0 | 0 | 0 | 0 |
| Start(...) | 0 | 0 | 0 | 0 |
| Class: | WireMock.Owin.AspNetCoreSelfHost |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Owin\AspNetCoreSelfHost.cs |
| Covered lines: | 81 |
| Uncovered lines: | 5 |
| Coverable lines: | 86 |
| Total lines: | 148 |
| Line coverage: | 94.1% |
| Branch coverage: | 75% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| StartAsync() | 0 | 0 | 1 | 0 |
| StartServers() | 0 | 0 | 0.688 | 0 |
| StopAsync() | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0.75 |
10 /// <summary>11 /// The body encoding.12 /// </summary>13 public Encoding Encoding { get; set; }13 public Encoding Encoding { get; set; }1415 /// <summary>16 /// The body as string.16 /// The body as string, this is defined when BodyAsString or BodyAsJson are not null.17 /// </summary>18 public string BodyAsString { get; set; }18 public string BodyAsString { get; set; }1920 /// <summary>21 /// The body (as JSON object).22 /// </summary>23 public object BodyAsJson { get; set; }23 public object BodyAsJson { get; set; }2425 /// <summary>26 /// The body (as bytearray).27 /// </summary>28 public byte[] BodyAsBytes { get; set; }28 public byte[] BodyAsBytes { get; set; }29 }30}| Class: | WireMock.Admin.Mappings.BodyModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\BodyModel.cs |
| Covered lines: | 1 |
| Uncovered lines: | 0 |
| Coverable lines: | 1 |
| Total lines: | 13 |
| Line coverage: | 100% |
| Class: | WireMock.Util.BodyParser |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\BodyParser.cs |
| Covered lines: | 39 |
| Uncovered lines: | 17 |
| Coverable lines: | 56 |
| Total lines: | 88 |
| Line coverage: | 69.6% |
| Branch coverage: | 39.2% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .cctor() | 0 | 0 | 1 | 0 |
| ReadStringAsync() | 0 | 0 | 1 | 0.5 |
| ReadBytesAsync() | 0 | 0 | 0 | 0 |
| Parse() | 0 | 0 | 0.633 | 0.45 |
17 {18 [ContractAnnotation("value:null => halt")]19 public static T Condition<T>([NoEnumeration] T value, [NotNull] Predicate<T> condition, [InvokerParameterName] [20 {21 NotNull(condition, nameof(condition));22 NotNull(value, nameof(value));20 {21 NotNull(condition, nameof(condition));22 NotNull(value, nameof(value));2324 if (!condition(value))25 {26 NotNullOrEmpty(parameterName, nameof(parameterName));24 if (!condition(value))25 {26 NotNullOrEmpty(parameterName, nameof(parameterName));2728 throw new ArgumentOutOfRangeException(parameterName);28 throw new ArgumentOutOfRangeException(parameterName);29 }3031 return value;32 }31 return value;32 }3334 [ContractAnnotation("value:null => halt")]35 public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)36 {37 if (ReferenceEquals(value, null))38 {39 NotNullOrEmpty(parameterName, nameof(parameterName));36 {37 if (ReferenceEquals(value, null))38 {39 NotNullOrEmpty(parameterName, nameof(parameterName));4041 throw new ArgumentNullException(parameterName);41 throw new ArgumentNullException(parameterName);42 }4344 return value;45 }44 return value;45 }4647 [ContractAnnotation("value:null => halt")]48 public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName, [NotN49 {50 if (ReferenceEquals(value, null))50 if (ReferenceEquals(value, null))51 {52 NotNullOrEmpty(parameterName, nameof(parameterName));53 NotNullOrEmpty(propertyName, nameof(propertyName));6061 [ContractAnnotation("value:null => halt")]62 public static IList<T> NotNullOrEmpty<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)63 {64 NotNull(value, parameterName);63 {64 NotNull(value, parameterName);6566 if (value.Count == 0)66 if (value.Count == 0)67 {68 NotNullOrEmpty(parameterName, nameof(parameterName));6970 throw new ArgumentException(CoreStrings.CollectionArgumentIsEmpty(parameterName));71 }7273 return value;74 }73 return value;74 }7576 [ContractAnnotation("value:null => halt")]77 public static string NotNullOrEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)78 {79 Exception e = null;80 if (ReferenceEquals(value, null))81 {82 e = new ArgumentNullException(parameterName);83 }84 else if (value.Trim().Length == 0)78 {79 Exception e = null;80 if (ReferenceEquals(value, null))81 {82 e = new ArgumentNullException(parameterName);83 }84 else if (value.Trim().Length == 0)85 {86 e = new ArgumentException(CoreStrings.ArgumentIsEmpty(parameterName));87 }8889 if (e != null)90 {91 NotNullOrEmpty(parameterName, nameof(parameterName));89 if (e != null)90 {91 NotNullOrEmpty(parameterName, nameof(parameterName));9293 throw e;93 throw e;94 }9596 return value;97 }96 return value;97 }9899 public static string NullButNotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)100 {101 if (!ReferenceEquals(value, null)101 if (!ReferenceEquals(value, null)102 && (value.Length == 0))103 {104 NotNullOrEmpty(parameterName, nameof(parameterName));111112 public static IList<T> HasNoNulls<T>(IList<T> value, [InvokerParameterName] [NotNull] string parameterName)113 where T : class114 {115 NotNull(value, parameterName);114 {115 NotNull(value, parameterName);116117 if (value.Any(e => e == null))117 if (value.Any(e => e == null))118 {119 NotNullOrEmpty(parameterName, nameof(parameterName));120121 throw new ArgumentException(parameterName);122 }123124 return value;125 }124 return value;125 }126127 public static Type ValidEntityType(Type value, [InvokerParameterName] [NotNull] string parameterName)128 {129 if (!value.GetTypeInfo().IsClass)129 if (!value.GetTypeInfo().IsClass)130 {131 NotNullOrEmpty(parameterName, nameof(parameterName));132139}1using System;2using System.Security.Cryptography.X509Certificates;34namespace WireMock.HttpsCertificate5{6 internal static class ClientCertificateHelper7 {8 public static X509Certificate2 GetCertificate(string thumbprintOrSubjectName)9 {10 X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);11 try12 {13 //Certificate must be in the local machine store14 certStore.Open(OpenFlags.ReadOnly);1516 //Attempt to find by thumbprint first17 var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjec18 if (matchingCertificates.Count == 0)19 {20 //Fallback to subject name21 matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubje22 if (matchingCertificates.Count == 0)23 {24 // No certificates matched the search criteria.25 throw new Exception($"No certificate found with Thumbprint or SubjectName '{thumbprintOrSubjectN26 }27 }28 // Use the first matching certificate.29 return matchingCertificates[0];30 }31 finally32 {33#if NETSTANDARD || NET4634 certStore.Dispose();35#else36 certStore.Close();37#endif38 }39 }40 }41}2using System.IO;3using System.Security.Cryptography.X509Certificates;45namespace WireMock.HttpsCertificate6{7 internal static class ClientCertificateHelper8 {9 public static X509Certificate2 GetCertificate(string thumbprintOrSubjectName)10 {11 X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);12 try13 {14 // Certificate must be in the local machine store15 certStore.Open(OpenFlags.ReadOnly);1617 // Attempt to find by thumbprint first18 var matchingCertificates = certStore.Certificates.Find(X509FindType.FindByThumbprint, thumbprintOrSubjec19 if (matchingCertificates.Count == 0)20 {21 // Fallback to subject name22 matchingCertificates = certStore.Certificates.Find(X509FindType.FindBySubjectName, thumbprintOrSubje23 if (matchingCertificates.Count == 0)24 {25 // No certificates matched the search criteria.26 throw new FileNotFoundException("No certificate found with specified Thumbprint or SubjectName."27 }28 }29 // Use the first matching certificate.30 return matchingCertificates[0];31 }32 finally33 {34#if NETSTANDARD || NET4635 certStore.Dispose();36#else37 certStore.Close();38#endif39 }40 }41 }42}| Class: | WireMock.Admin.Mappings.ClientIPModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\ClientIPModel.cs |
| Covered lines: | 0 |
| Uncovered lines: | 1 |
| Coverable lines: | 1 |
| Total lines: | 13 |
| Line coverage: | 0% |
10 /// <inheritdoc cref="ObservableCollection{T}" />11 public class ConcurentObservableCollection<T> : ObservableCollection<T>12 {13 private readonly object _lockObject = new object();13 private readonly object _lockObject = new object();1415 /// <summary>16 /// Initializes a new instance of the <see cref="T:WireMock.Util.ConcurentObservableCollection`1" /> class.17 /// </summary>18 public ConcurentObservableCollection() { }18 public ConcurentObservableCollection() { }1920 /// <summary>21 /// Initializes a new instance of the <see cref="ConcurentObservableCollection{T}"/> class that contains element3132 /// <inheritdoc cref="ObservableCollection{T}.ClearItems"/>33 protected override void ClearItems()34 {35 lock (_lockObject)36 {37 base.ClearItems();38 }39 }34 {35 lock (_lockObject)36 {37 base.ClearItems();38 }39 }4041 /// <inheritdoc cref="ObservableCollection{T}.RemoveItem"/>42 protected override void RemoveItem(int index)4950 /// <inheritdoc cref="ObservableCollection{T}.InsertItem"/>51 protected override void InsertItem(int index, T item)52 {53 lock (_lockObject)54 {55 base.InsertItem(index, item);56 }57 }52 {53 lock (_lockObject)54 {55 base.InsertItem(index, item);56 }57 }5859 /// <inheritdoc cref="ObservableCollection{T}.SetItem"/>60 protected override void SetItem(int index, T item)77}41}| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
| Loop(...) | 4 | 2 | 100 | 100 |
| Loop(...) | 0 | 0 | 0 | 0 |
18 /// <param name="dictionary">The dictionary to loop (can be null).</param>19 /// <param name="action">The action.</param>20 public static void Loop<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, [NotNull] Action<TKey, TValue> 21 {22 Check.NotNull(action, nameof(action));21 {22 Check.NotNull(action, nameof(action));2324 if (dictionary != null)25 {26 foreach (var entry in dictionary)27 {28 action(entry.Key, entry.Value);29 }30 }31 }24 if (dictionary != null)25 {26 foreach (var entry in dictionary)27 {28 action(entry.Key, entry.Value);29 }30 }31 }32 }33}24}9 {10 private readonly Func<RequestMessage, ResponseMessage> _responseMessageFunc;1112 public DynamicResponseProvider([NotNull] Func<RequestMessage, ResponseMessage> responseMessageFunc)13 {14 Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));12 public DynamicResponseProvider([NotNull] Func<RequestMessage, ResponseMessage> responseMessageFunc)13 {14 Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));1516 _responseMessageFunc = responseMessageFunc;17 }16 _responseMessageFunc = responseMessageFunc;17 }1819 public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)20 {21 return Task.FromResult(_responseMessageFunc(requestMessage));22 }20 {21 return Task.FromResult(_responseMessageFunc(requestMessage));22 }23 }24}8 /// <summary>9 /// Encoding CodePage10 /// </summary>11 public int CodePage { get; set; }11 public int CodePage { get; set; }1213 /// <summary>14 /// Encoding EncodingName15 /// </summary>16 public string EncodingName { get; set; }16 public string EncodingName { get; set; }1718 /// <summary>19 /// Encoding WebName20 /// </summary>21 public string WebName { get; set; }21 public string WebName { get; set; }22 }23}9 /// <summary>10 /// An EnhancedFileSystemWatcher, which can be used to suppress duplicate events that fire on a single change to the11 /// </summary>12 /// <seealso cref="System.IO.FileSystemWatcher" />13 /// <seealso cref="System.IDisposable" />14 public class EnhancedFileSystemWatcher : FileSystemWatcher, IDisposable15 {16 #region Private Members17 // Default Watch Interval in Milliseconds18 private const int DefaultWatchInterval = 100;1920 // This Dictionary keeps the track of when an event occured last for a particular file21 private ConcurrentDictionary<string, DateTime> _lastFileEvent;2223 // Watch Interval in Milliseconds24 private int _interval;2526 // Timespan created when interval is set27 private TimeSpan _recentTimeSpan;28 #endregion2930 #region Public Properties31 /// <summary>32 /// Interval, in milliseconds, within which events are considered "recent".33 /// </summary>34 [PublicAPI]35 public int Interval36 {37 get => _interval;38 set39 {40 _interval = value;4142 // Set timespan based on the value passed43 _recentTimeSpan = new TimeSpan(0, 0, 0, 0, value);44 }45 }4647 /// <summary>48 /// Allows user to set whether to filter recent events.49 /// If this is set a false, this class behaves like System.IO.FileSystemWatcher class.50 /// </summary>51 [PublicAPI]52 public bool FilterRecentEvents { get; set; }53 #endregion5455 #region Constructors56 /// <summary>57 /// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.58 /// </summary>59 /// <param name="interval">The interval.</param>60 public EnhancedFileSystemWatcher(int interval = DefaultWatchInterval)61 {62 Check.Condition(interval, i => i >= 0, nameof(interval));6364 InitializeMembers(interval);65 }6667 /// <summary>68 /// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.69 /// </summary>70 /// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</par71 /// <param name="interval">The interval.</param>72 public EnhancedFileSystemWatcher([NotNull] string path, int interval = DefaultWatchInterval) : base(path)73 {74 Check.NotNullOrEmpty(path, nameof(path));75 Check.Condition(interval, i => i >= 0, nameof(interval));7677 InitializeMembers(interval);78 }7980 /// <summary>81 /// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.82 /// </summary>83 /// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</par84 /// <param name="filter">The type of files to watch. For example, "*.txt" watches for changes to all text files.85 /// <param name="interval">The interval.</param>86 public EnhancedFileSystemWatcher([NotNull] string path, [NotNull] string filter, int interval = DefaultWatchInte87 {88 Check.NotNullOrEmpty(path, nameof(path));89 Check.NotNullOrEmpty(filter, nameof(filter));90 Check.Condition(interval, i => i >= 0, nameof(interval));9192 InitializeMembers(interval);93 }94 #endregion9596 #region Events97 // These events hide the events from the base class.98 // We want to raise these events appropriately and we do not want the99 // users of this class subscribing to these events of the base class accidentally100101 /// <summary>102 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is change103 /// </summary>104 public new event FileSystemEventHandler Changed;105106 /// <summary>107 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is create108 /// </summary>109 public new event FileSystemEventHandler Created;110111 /// <summary>112 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is delete113 /// </summary>114 public new event FileSystemEventHandler Deleted;115116 /// <summary>117 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is rename118 /// </summary>119 public new event RenamedEventHandler Renamed;120 #endregion121122 #region Protected Methods to raise the Events for this class123 /// <summary>124 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Changed" /> event.125 /// </summary>126 /// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>127 protected new virtual void OnChanged(FileSystemEventArgs e)128 {129 Changed?.Invoke(this, e);130 }131132 /// <summary>133 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Created" /> event.134 /// </summary>135 /// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>136 protected new virtual void OnCreated(FileSystemEventArgs e)137 {138 Created?.Invoke(this, e);139 }140141 /// <summary>142 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Deleted" /> event.143 /// </summary>144 /// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>145 protected new virtual void OnDeleted(FileSystemEventArgs e)146 {147 Deleted?.Invoke(this, e);148 }149150 /// <summary>151 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Renamed" /> event.152 /// </summary>153 /// <param name="e">A <see cref="T:System.IO.RenamedEventArgs" /> that contains the event data.</param>154 protected new virtual void OnRenamed(RenamedEventArgs e)155 {156 Renamed?.Invoke(this, e);157 }158 #endregion159160 #region Private Methods161 /// <summary>162 /// This Method Initializes the private members.163 /// Interval is set to its default value of 100 millisecond.164 /// FilterRecentEvents is set to true, _lastFileEvent dictionary is initialized.165 /// We subscribe to the base class events.166 /// </summary>167 private void InitializeMembers(int interval = 100)168 {169 Interval = interval;170 FilterRecentEvents = true;171 _lastFileEvent = new ConcurrentDictionary<string, DateTime>();172173 base.Created += OnCreated;174 base.Changed += OnChanged;175 base.Deleted += OnDeleted;176 base.Renamed += OnRenamed;177 }178179 /// <summary>180 /// This method searches the dictionary to find out when the last event occured181 /// for a particular file. If that event occured within the specified timespan182 /// it returns true, else false183 /// </summary>184 /// <param name="fileName">The filename to be checked</param>185 /// <returns>True if an event has occured within the specified interval, False otherwise</returns>186 private bool HasAnotherFileEventOccuredRecently(string fileName)187 {188 // Check dictionary only if user wants to filter recent events otherwise return value stays false.189 if (!FilterRecentEvents)190 {191 return false;192 }193194 bool retVal = false;195 if (_lastFileEvent.ContainsKey(fileName))196 {197 // If dictionary contains the filename, check how much time has elapsed198 // since the last event occured. If the timespan is less that the199 // specified interval, set return value to true200 // and store current datetime in dictionary for this file201 DateTime lastEventTime = _lastFileEvent[fileName];202 DateTime currentTime = DateTime.Now;203 TimeSpan timeSinceLastEvent = currentTime - lastEventTime;204 retVal = timeSinceLastEvent < _recentTimeSpan;205 _lastFileEvent[fileName] = currentTime;206 }207 else208 {209 // If dictionary does not contain the filename,210 // no event has occured in past for this file, so set return value to false211 // and append filename along with current datetime to the dictionary212 _lastFileEvent.TryAdd(fileName, DateTime.Now);213 }214215 return retVal;216 }217218 #region FileSystemWatcher EventHandlers219 // Base class Event Handlers. Check if an event has occured recently and call method220 // to raise appropriate event only if no recent event is detected221 private void OnChanged(object sender, FileSystemEventArgs e)222 {223 if (!HasAnotherFileEventOccuredRecently(e.FullPath))224 {225 OnChanged(e);226 }227 }228229 private void OnCreated(object sender, FileSystemEventArgs e)230 {231 if (!HasAnotherFileEventOccuredRecently(e.FullPath))232 {233 OnCreated(e);234 }235 }236237 private void OnDeleted(object sender, FileSystemEventArgs e)238 {239 if (!HasAnotherFileEventOccuredRecently(e.FullPath))240 {241 OnDeleted(e);242 }243 }244245 private void OnRenamed(object sender, RenamedEventArgs e)246 {247 if (!HasAnotherFileEventOccuredRecently(e.OldFullPath))248 {249 OnRenamed(e);250 }251 }12 /// <seealso cref="FileSystemWatcher" />13 public class EnhancedFileSystemWatcher : FileSystemWatcher14 {15 #region Private Members16 // Default Watch Interval in Milliseconds17 private const int DefaultWatchInterval = 100;1819 // This Dictionary keeps the track of when an event occured last for a particular file20 private ConcurrentDictionary<string, DateTime> _lastFileEvent;2122 // Watch Interval in Milliseconds23 private int _interval;2425 // Timespan created when interval is set26 private TimeSpan _recentTimeSpan;27 #endregion2829 #region Public Properties30 /// <summary>31 /// Interval, in milliseconds, within which events are considered "recent".32 /// </summary>33 [PublicAPI]34 public int Interval35 {36 get => _interval;37 set38 {39 _interval = value;4041 // Set timespan based on the value passed42 _recentTimeSpan = new TimeSpan(0, 0, 0, 0, value);43 }44 }4546 /// <summary>47 /// Allows user to set whether to filter recent events.48 /// If this is set a false, this class behaves like System.IO.FileSystemWatcher class.49 /// </summary>50 [PublicAPI]51 public bool FilterRecentEvents { get; set; }52 #endregion5354 #region Constructors55 /// <summary>56 /// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.57 /// </summary>58 /// <param name="interval">The interval.</param>59 public EnhancedFileSystemWatcher(int interval = DefaultWatchInterval)60 {61 Check.Condition(interval, i => i >= 0, nameof(interval));6263 InitializeMembers(interval);64 }6566 /// <summary>67 /// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.68 /// </summary>69 /// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</par70 /// <param name="interval">The interval.</param>71 public EnhancedFileSystemWatcher([NotNull] string path, int interval = DefaultWatchInterval) : base(path)72 {73 Check.NotNullOrEmpty(path, nameof(path));74 Check.Condition(interval, i => i >= 0, nameof(interval));7576 InitializeMembers(interval);77 }7879 /// <summary>80 /// Initializes a new instance of the <see cref="EnhancedFileSystemWatcher"/> class.81 /// </summary>82 /// <param name="path">The directory to monitor, in standard or Universal Naming Convention (UNC) notation.</par83 /// <param name="filter">The type of files to watch. For example, "*.txt" watches for changes to all text files.84 /// <param name="interval">The interval.</param>85 public EnhancedFileSystemWatcher([NotNull] string path, [NotNull] string filter, int interval = DefaultWatchInte86 {87 Check.NotNullOrEmpty(path, nameof(path));88 Check.NotNullOrEmpty(filter, nameof(filter));89 Check.Condition(interval, i => i >= 0, nameof(interval));9091 InitializeMembers(interval);92 }93 #endregion9495 #region Events96 // These events hide the events from the base class.97 // We want to raise these events appropriately and we do not want the98 // users of this class subscribing to these events of the base class accidentally99100 /// <summary>101 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is change102 /// </summary>103 public new event FileSystemEventHandler Changed;104105 /// <summary>106 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is create107 /// </summary>108 public new event FileSystemEventHandler Created;109110 /// <summary>111 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is delete112 /// </summary>113 public new event FileSystemEventHandler Deleted;114115 /// <summary>116 /// Occurs when a file or directory in the specified <see cref="P:System.IO.FileSystemWatcher.Path" /> is rename117 /// </summary>118 public new event RenamedEventHandler Renamed;119 #endregion120121 #region Protected Methods to raise the Events for this class122 /// <summary>123 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Changed" /> event.124 /// </summary>125 /// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>126 protected new virtual void OnChanged(FileSystemEventArgs e)127 {128 Changed?.Invoke(this, e);129 }130131 /// <summary>132 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Created" /> event.133 /// </summary>134 /// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>135 protected new virtual void OnCreated(FileSystemEventArgs e)136 {137 Created?.Invoke(this, e);138 }139140 /// <summary>141 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Deleted" /> event.142 /// </summary>143 /// <param name="e">A <see cref="T:System.IO.FileSystemEventArgs" /> that contains the event data.</param>144 protected new virtual void OnDeleted(FileSystemEventArgs e)145 {146 Deleted?.Invoke(this, e);147 }148149 /// <summary>150 /// Raises the <see cref="E:System.IO.FileSystemWatcher.Renamed" /> event.151 /// </summary>152 /// <param name="e">A <see cref="T:System.IO.RenamedEventArgs" /> that contains the event data.</param>153 protected new virtual void OnRenamed(RenamedEventArgs e)154 {155 Renamed?.Invoke(this, e);156 }157 #endregion158159 #region Private Methods160 /// <summary>161 /// This Method Initializes the private members.162 /// Interval is set to its default value of 100 millisecond.163 /// FilterRecentEvents is set to true, _lastFileEvent dictionary is initialized.164 /// We subscribe to the base class events.165 /// </summary>166 private void InitializeMembers(int interval = 100)167 {168 Interval = interval;169 FilterRecentEvents = true;170 _lastFileEvent = new ConcurrentDictionary<string, DateTime>();171172 base.Created += OnCreated;173 base.Changed += OnChanged;174 base.Deleted += OnDeleted;175 base.Renamed += OnRenamed;176 }177178 /// <summary>179 /// This method searches the dictionary to find out when the last event occured180 /// for a particular file. If that event occured within the specified timespan181 /// it returns true, else false182 /// </summary>183 /// <param name="fileName">The filename to be checked</param>184 /// <returns>True if an event has occured within the specified interval, False otherwise</returns>185 private bool HasAnotherFileEventOccuredRecently(string fileName)186 {187 // Check dictionary only if user wants to filter recent events otherwise return value stays false.188 if (!FilterRecentEvents)189 {190 return false;191 }192193 bool retVal = false;194 if (_lastFileEvent.ContainsKey(fileName))195 {196 // If dictionary contains the filename, check how much time has elapsed197 // since the last event occured. If the timespan is less that the198 // specified interval, set return value to true199 // and store current datetime in dictionary for this file200 DateTime lastEventTime = _lastFileEvent[fileName];201 DateTime currentTime = DateTime.Now;202 TimeSpan timeSinceLastEvent = currentTime - lastEventTime;203 retVal = timeSinceLastEvent < _recentTimeSpan;204 _lastFileEvent[fileName] = currentTime;205 }206 else207 {208 // If dictionary does not contain the filename,209 // no event has occured in past for this file, so set return value to false210 // and append filename along with current datetime to the dictionary211 _lastFileEvent.TryAdd(fileName, DateTime.Now);212 }213214 return retVal;215 }216217 #region FileSystemWatcher EventHandlers218 // Base class Event Handlers. Check if an event has occured recently and call method219 // to raise appropriate event only if no recent event is detected220 private void OnChanged(object sender, FileSystemEventArgs e)221 {222 if (!HasAnotherFileEventOccuredRecently(e.FullPath))223 {224 OnChanged(e);225 }226 }227228 private void OnCreated(object sender, FileSystemEventArgs e)229 {230 if (!HasAnotherFileEventOccuredRecently(e.FullPath))231 {232 OnCreated(e);233 }234 }235236 private void OnDeleted(object sender, FileSystemEventArgs e)237 {238 if (!HasAnotherFileEventOccuredRecently(e.FullPath))239 {240 OnDeleted(e);241 }242 }243244 private void OnRenamed(object sender, RenamedEventArgs e)245 {246 if (!HasAnotherFileEventOccuredRecently(e.OldFullPath))247 {248 OnRenamed(e);249 }250 }251 #endregion252 #endregion253 #endregion254255 #region IDisposable Members256 /// <summary>257 /// Releases all resources used by the <see cref="T:System.ComponentModel.Component" />.258 /// </summary>259 public new void Dispose()260 {261 base.Dispose();262 }263 #endregion264 }265}253 }254}| Class: | WireMock.Matchers.ExactMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\ExactMatcher.cs |
| Covered lines: | 17 |
| Uncovered lines: | 0 |
| Coverable lines: | 17 |
| Total lines: | 54 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| IsMatch(...) | 0 | 0 | 1 | 0 |
| GetPatterns() | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| Class: | WireMock.Matchers.ExactObjectMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\ExactObjectMatcher.cs |
| Covered lines: | 24 |
| Uncovered lines: | 0 |
| Coverable lines: | 24 |
| Total lines: | 71 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| IsMatch(...) | 0 | 0 | 1 | 1 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| Class: | WireMock.Util.FileHelper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\FileHelper.cs |
| Covered lines: | 14 |
| Uncovered lines: | 0 |
| Coverable lines: | 14 |
| Total lines: | 34 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| ReadAllTextWithRetryAndDelay(...) | 0 | 0 | 1 | 1 |
9using Newtonsoft.Json;10using Newtonsoft.Json.Linq;11using WireMock.Admin.Mappings;12using WireMock.Admin.Requests;12using WireMock.Admin.Scenarios;13using WireMock.Admin.Settings;14using WireMock.Http;15using WireMock.Logging;30 /// </summary>31 public partial class FluentMockServer32 {33 private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");34 private const string ContentTypeJson = "application/json";33 private const string ContentTypeJson = "application/json";3435 private const string AdminMappings = "/__admin/mappings";36 private const string AdminRequests = "/__admin/requests";37 private const string AdminSettings = "/__admin/settings";38 private const string AdminScenarios = "/__admin/scenarios";39 private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/mappings\/(\{{0,1}(40 private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/requests\/(\{{0,1}(4142 private readonly JsonSerializerSettings _settings = new JsonSerializerSettings43 {44 Formatting = Formatting.Indented,45 NullValueHandling = NullValueHandling.Ignore,46 };4748 #region InitAdmin49 private void InitAdmin()50 {51 // __admin/settings52 Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsG53 Given(Request.Create().WithPath(AdminSettings).UsingVerb("PUT", "POST").WithHeader(HttpKnownHeaderNames.Cont3940 private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^41 private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(MatchBehaviour.AcceptOnMatch, @"^4243 private readonly JsonSerializerSettings _settings = new JsonSerializerSettings44 {45 Formatting = Formatting.Indented,46 NullValueHandling = NullValueHandling.Ignore47 };4849 private readonly JsonSerializerSettings _settingsIncludeNullValues = new JsonSerializerSettings50 {51 Formatting = Formatting.Indented,52 NullValueHandling = NullValueHandling.Include53 };545556 // __admin/mappings57 Given(Request.Create().WithPath(AdminMappings).UsingGet()).RespondWith(new DynamicResponseProvider(MappingsG58 Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, Cont59 Given(Request.Create().WithPath(AdminMappings).UsingDelete()).RespondWith(new DynamicResponseProvider(Mappin6061 // __admin/mappings/reset62 Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).RespondWith(new DynamicResponseProvid6364 // __admin/mappings/{guid}65 Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponsePr66 Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.Co67 Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicRespons6869 // __admin/mappings/save70 Given(Request.Create().WithPath(AdminMappings + "/save").UsingPost()).RespondWith(new DynamicResponseProvide717273 // __admin/requests74 Given(Request.Create().WithPath(AdminRequests).UsingGet()).RespondWith(new DynamicResponseProvider(RequestsG75 Given(Request.Create().WithPath(AdminRequests).UsingDelete()).RespondWith(new DynamicResponseProvider(Reques7677 // __admin/requests/reset78 Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).RespondWith(new DynamicResponseProvid55 #region InitAdmin56 private void InitAdmin()57 {58 // __admin/settings59 Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsG60 Given(Request.Create().WithPath(AdminSettings).UsingMethod("PUT", "POST").WithHeader(HttpKnownHeaderNames.Co616263 // __admin/mappings64 Given(Request.Create().WithPath(AdminMappings).UsingGet()).RespondWith(new DynamicResponseProvider(MappingsG65 Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, Cont66 Given(Request.Create().WithPath(AdminMappings).UsingDelete()).RespondWith(new DynamicResponseProvider(Mappin6768 // __admin/mappings/reset69 Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).RespondWith(new DynamicResponseProvid7071 // __admin/mappings/{guid}72 Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponsePr73 Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.Co74 Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicRespons7576 // __admin/mappings/save77 Given(Request.Create().WithPath(AdminMappings + "/save").UsingPost()).RespondWith(new DynamicResponseProvide787980 // __admin/request/{guid}81 Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponsePr82 Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicRespons80 // __admin/requests81 Given(Request.Create().WithPath(AdminRequests).UsingGet()).RespondWith(new DynamicResponseProvider(RequestsG82 Given(Request.Create().WithPath(AdminRequests).UsingDelete()).RespondWith(new DynamicResponseProvider(Reques8384 // __admin/requests/find85 Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).RespondWith(new DynamicResponseProvide84 // __admin/requests/reset85 Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).RespondWith(new DynamicResponseProvid868788 // __admin/scenarios89 Given(Request.Create().WithPath(AdminScenarios).UsingGet()).RespondWith(new DynamicResponseProvider(Scenario90 Given(Request.Create().WithPath(AdminScenarios).UsingDelete()).RespondWith(new DynamicResponseProvider(Scena9192 // __admin/scenarios/reset93 Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvi94 }95 #endregion9697 #region StaticMappings98 /// <summary>99 /// Reads the static mappings from a folder.100 /// </summary>101 /// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>102 [PublicAPI]103 public void ReadStaticMappings([CanBeNull] string folder = null)104 {105 if (folder == null)106 {107 folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);108 }109110 if (!Directory.Exists(folder))111 {112 return;113 }114115 foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))116 {117 _logger.Info("Reading Static MappingFile : '{0}'", filename);118 ReadStaticMappingAndAddOrUpdate(filename);119 }120 }121122 /// <summary>123 /// Watches the static mappings for changes.124 /// </summary>125 /// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>126 [PublicAPI]127 public void WatchStaticMappings([CanBeNull] string folder = null)128 {129 if (folder == null)130 {131 folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);132 }133134 if (!Directory.Exists(folder))135 {136 return;137 }138139 _logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);140141 var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 1000);142 watcher.Created += (sender, args) =>143 {144 _logger.Info("New MappingFile created : '{0}'", args.FullPath);145 ReadStaticMappingAndAddOrUpdate(args.FullPath);146 };147 watcher.Changed += (sender, args) =>148 {149 _logger.Info("New MappingFile updated : '{0}'", args.FullPath);150 ReadStaticMappingAndAddOrUpdate(args.FullPath);151 };152 watcher.Deleted += (sender, args) =>153 {154 _logger.Info("New MappingFile deleted : '{0}'", args.FullPath);155 string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);156157 if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))158 {159 DeleteMapping(guidFromFilename);160 }161 else162 {163 DeleteMapping(args.FullPath);164 }165 };166167 watcher.EnableRaisingEvents = true;168 }87 // __admin/request/{guid}88 Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponsePr89 Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicRespons9091 // __admin/requests/find92 Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).RespondWith(new DynamicResponseProvide939495 // __admin/scenarios96 Given(Request.Create().WithPath(AdminScenarios).UsingGet()).RespondWith(new DynamicResponseProvider(Scenario97 Given(Request.Create().WithPath(AdminScenarios).UsingDelete()).RespondWith(new DynamicResponseProvider(Scena9899 // __admin/scenarios/reset100 Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvi101 }102 #endregion103104 #region StaticMappings105 /// <summary>106 /// Saves the static mappings.107 /// </summary>108 /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>109 [PublicAPI]110 public void SaveStaticMappings([CanBeNull] string folder = null)111 {112 foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))113 {114 SaveMappingToFile(mapping, folder);115 }116 }117118 /// <summary>119 /// Reads the static mappings from a folder.120 /// </summary>121 /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>122 [PublicAPI]123 public void ReadStaticMappings([CanBeNull] string folder = null)124 {125 if (folder == null)126 {127 folder = _fileSystemHandler.GetMappingFolder();128 }129130 if (!_fileSystemHandler.FolderExists(folder))131 {132 _logger.Info("The Static Mapping folder '{0}' does not exist, reading Static MappingFiles will be skippe133 return;134 }135136 foreach (string filename in _fileSystemHandler.EnumerateFiles(folder).OrderBy(f => f))137 {138 _logger.Info("Reading Static MappingFile : '{0}'", filename);139140 try141 {142 ReadStaticMappingAndAddOrUpdate(filename);143 }144 catch145 {146 _logger.Error("Static MappingFile : '{0}' could not be read. This file will be skipped.", filename);147 }148 }149 }150151 /// <summary>152 /// Watches the static mappings for changes.153 /// </summary>154 /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>155 [PublicAPI]156 public void WatchStaticMappings([CanBeNull] string folder = null)157 {158 if (folder == null)159 {160 folder = _fileSystemHandler.GetMappingFolder();161 }162163 if (!_fileSystemHandler.FolderExists(folder))164 {165 return;166 }167168 _logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);169170 /// <summary>171 /// Reads a static mapping file and adds or updates the mapping.172 /// </summary>173 /// <param name="path">The path.</param>174 [PublicAPI]175 public void ReadStaticMappingAndAddOrUpdate([NotNull] string path)176 {177 Check.NotNull(path, nameof(path));178179 string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);180181 MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(FileHelper.ReadAllText(path));182 if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))183 {184 DeserializeAndAddOrUpdateMapping(mappingModel, guidFromFilename, path);185 }186 else187 {188 DeserializeAndAddOrUpdateMapping(mappingModel, null, path);189 }190 }191 #endregion192193 #region Proxy and Record194 private HttpClient _httpClientForProxy;170 var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 1000);171 watcher.Created += (sender, args) =>172 {173 _logger.Info("New MappingFile created : '{0}'", args.FullPath);174 ReadStaticMappingAndAddOrUpdate(args.FullPath);175 };176 watcher.Changed += (sender, args) =>177 {178 _logger.Info("New MappingFile updated : '{0}'", args.FullPath);179 ReadStaticMappingAndAddOrUpdate(args.FullPath);180 };181 watcher.Deleted += (sender, args) =>182 {183 _logger.Info("New MappingFile deleted : '{0}'", args.FullPath);184 string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);185186 if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))187 {188 DeleteMapping(guidFromFilename);189 }190 else191 {192 DeleteMapping(args.FullPath);193 }194 };195196 private void InitProxyAndRecord(IProxyAndRecordSettings settings)197 {198 _httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ClientX509Certificate2ThumbprintOrSubjectNa199 Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRec200 }201202 private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings s203 {204 var requestUri = new Uri(requestMessage.Url);205 var proxyUri = new Uri(settings.Url);206 var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);196 watcher.EnableRaisingEvents = true;197 }198199 /// <summary>200 /// Reads a static mapping file and adds or updates the mapping.201 /// </summary>202 /// <param name="path">The path.</param>203 [PublicAPI]204 public void ReadStaticMappingAndAddOrUpdate([NotNull] string path)205 {206 Check.NotNull(path, nameof(path));207208 var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequ208 string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);209210 if (settings.SaveMapping)211 {212 var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { }213 _options.Mappings.Add(mapping.Guid, mapping);214215 if (settings.SaveMappingToFile)216 {217 SaveMappingToFile(mapping);218 }219 }220221 return responseMessage;222 }223224 private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage, string[] blacklistedHe225 {226 var request = Request.Create();227 request.WithPath(requestMessage.Path);228 request.UsingVerb(requestMessage.Method);229230 requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));231 requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));232233 var allBlackListedHeaders = new List<string>(blacklistedHeaders) { "Cookie" };234 requestMessage.Headers.Loop((key, value) =>235 {236 if (!allBlackListedHeaders.Any(b => string.Equals(key, b, StringComparison.OrdinalIgnoreCase)))237 {238 request.WithHeader(key, value.ToArray());239 }240 });241242 if (requestMessage.Body != null)243 {244 request.WithBody(new ExactMatcher(requestMessage.Body));245 }246247 var response = Response.Create(responseMessage);248249 return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);250 }251 #endregion210 MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(_fileSystemHandler.ReadMappingFile(p211 if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))212 {213 DeserializeAndAddOrUpdateMapping(mappingModel, guidFromFilename, path);214 }215 else216 {217 DeserializeAndAddOrUpdateMapping(mappingModel, null, path);218 }219 }220 #endregion221222 #region Proxy and Record223 private HttpClient _httpClientForProxy;224225 private void InitProxyAndRecord(IProxyAndRecordSettings settings)226 {227 _httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ClientX509Certificate2ThumbprintOrSubjectNa228 Given(Request.Create().WithPath("/*").UsingAnyMethod()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndR229 }230231 private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings s232 {233 var requestUri = new Uri(requestMessage.Url);234 var proxyUri = new Uri(settings.Url);235 var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);236237 var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequ238239 if (settings.SaveMapping)240 {241 var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { }242 _options.Mappings.TryAdd(mapping.Guid, mapping);243244 if (settings.SaveMappingToFile)245 {246 SaveMappingToFile(mapping);247 }248 }249250 return responseMessage;251 }252253 #region Settings254 private ResponseMessage SettingsGet(RequestMessage requestMessage)255 {256 var model = new SettingsModel257 {258 AllowPartialMapping = _options.AllowPartialMapping,259 MaxRequestLogCount = _options.MaxRequestLogCount,260 RequestLogExpirationDuration = _options.RequestLogExpirationDuration,261 GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds262 };263264 return ToJson(model);265 }266267 private ResponseMessage SettingsUpdate(RequestMessage requestMessage)268 {269 var settings = requestMessage.Body != null ? JsonConvert.DeserializeObject<SettingsModel>(requestMessage.Bod253 private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage, string[] blacklistedHe254 {255 var request = Request.Create();256 request.WithPath(requestMessage.Path);257 request.UsingMethod(requestMessage.Method);258259 requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));260 requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));261262 var allBlackListedHeaders = new List<string>(blacklistedHeaders) { "Cookie" };263 requestMessage.Headers.Loop((key, value) =>264 {265 if (!allBlackListedHeaders.Any(b => string.Equals(key, b, StringComparison.OrdinalIgnoreCase)))266 {267 request.WithHeader(key, value.ToArray());268 }269 });270271 if (settings.AllowPartialMapping != null)272 _options.AllowPartialMapping = settings.AllowPartialMapping.Value;273274 _options.MaxRequestLogCount = settings.MaxRequestLogCount;275276 _options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;277278 if (settings.GlobalProcessingDelay != null)279 _options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);280281 return new ResponseMessage { Body = "Settings updated" };282 }283 #endregion Settings284285 #region Mapping/{guid}286 private ResponseMessage MappingGet(RequestMessage requestMessage)287 {288 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));289 var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);290291 if (mapping == null)292 {293 _logger.Warn("HttpStatusCode set to 404 : Mapping not found");294 return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };295 }271 if (requestMessage.BodyAsJson != null)272 {273 request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));274 }275 else if (requestMessage.Body != null)276 {277 request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));278 }279280 var response = Response.Create(responseMessage);281282 return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);283 }284 #endregion285286 #region Settings287 private ResponseMessage SettingsGet(RequestMessage requestMessage)288 {289 var model = new SettingsModel290 {291 AllowPartialMapping = _options.AllowPartialMapping,292 MaxRequestLogCount = _options.MaxRequestLogCount,293 RequestLogExpirationDuration = _options.RequestLogExpirationDuration,294 GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds295 };296297 var model = MappingConverter.ToMappingModel(mapping);298299 return ToJson(model);300 }301302 private ResponseMessage MappingPut(RequestMessage requestMessage)303 {304 Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));297 return ToJson(model);298 }299300 private ResponseMessage SettingsUpdate(RequestMessage requestMessage)301 {302 var settings = DeserializeObject<SettingsModel>(requestMessage);303 _options.MaxRequestLogCount = settings.MaxRequestLogCount;304 _options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;305306 MappingModel mappingModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<MappingModel>(reques307 DeserializeAndAddOrUpdateMapping(mappingModel, guid);308309 return new ResponseMessage { Body = "Mapping added or updated" };310 }311312 private ResponseMessage MappingDelete(RequestMessage requestMessage)313 {314 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));306 if (settings.AllowPartialMapping != null)307 {308 _options.AllowPartialMapping = settings.AllowPartialMapping.Value;309 }310311 if (settings.GlobalProcessingDelay != null)312 {313 _options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);314 }315316 if (DeleteMapping(guid))317 {318 return new ResponseMessage { Body = "Mapping removed" };319 }320321 return new ResponseMessage { Body = "Mapping not found" };322 }323 #endregion Mapping/{guid}324325 #region Mappings326 private ResponseMessage MappingsSave(RequestMessage requestMessage)327 {328 foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))329 {330 SaveMappingToFile(mapping);331 }332333 return new ResponseMessage { Body = "Mappings saved to disk" };334 }335336 private void SaveMappingToFile(Mapping mapping)337 {338 string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);339 if (!Directory.Exists(folder))340 {341 Directory.CreateDirectory(folder);342 }316 return ResponseMessageBuilder.Create("Settings updated");317 }318 #endregion Settings319320 #region Mapping/{guid}321 private ResponseMessage MappingGet(RequestMessage requestMessage)322 {323 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));324 var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);325326 if (mapping == null)327 {328 _logger.Warn("HttpStatusCode set to 404 : Mapping not found");329 return ResponseMessageBuilder.Create("Mapping not found", 404);330 }331332 var model = MappingConverter.ToMappingModel(mapping);333334 return ToJson(model);335 }336337 private ResponseMessage MappingPut(RequestMessage requestMessage)338 {339 Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));340341 var mappingModel = DeserializeObject<MappingModel>(requestMessage);342 Guid? guidFromPut = DeserializeAndAddOrUpdateMapping(mappingModel, guid);343344 var model = MappingConverter.ToMappingModel(mapping);345 string filename = !string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToSt344 return ResponseMessageBuilder.Create("Mapping added or updated", 200, guidFromPut);345 }346347 string filePath = Path.Combine(folder, filename + ".json");348 _logger.Info("Saving Mapping to file {0}", filePath);349350 File.WriteAllText(filePath, JsonConvert.SerializeObject(model, _settings));351 }352353 private static string SanitizeFileName(string name, char replaceChar = '_')354 {355 return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));356 }357358 private ResponseMessage MappingsGet(RequestMessage requestMessage)359 {360 var result = new List<MappingModel>();361 foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))362 {363 var model = MappingConverter.ToMappingModel(mapping);364 result.Add(model);365 }366367 return ToJson(result);368 }369370 private ResponseMessage MappingsPost(RequestMessage requestMessage)371 {372 try373 {374 MappingModel mappingModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<MappingModel>(re375 DeserializeAndAddOrUpdateMapping(mappingModel);376 }377 catch (ArgumentException a)378 {379 _logger.Error("HttpStatusCode set to 400 {0}", a);380 return new ResponseMessage { StatusCode = 400, Body = a.Message };381 }382 catch (Exception e)383 {384 _logger.Error("HttpStatusCode set to 500 {0}", e);385 return new ResponseMessage { StatusCode = 500, Body = e.ToString() };386 }387388 return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };389 }390391 private void DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)392 {393 Check.NotNull(mappingModel, nameof(mappingModel));394 Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));395 Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));396397 var requestBuilder = InitRequestBuilder(mappingModel.Request);398 var responseBuilder = InitResponseBuilder(mappingModel.Response);399400 IRespondWithAProvider respondProvider = Given(requestBuilder);401402 if (guid != null)403 {404 respondProvider = respondProvider.WithGuid(guid.Value);405 }406 else if (mappingModel.Guid != null && mappingModel.Guid != Guid.Empty)407 {408 respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);409 }410411 if (path != null)412 {413 respondProvider = respondProvider.WithPath(path);414 }415416 if (!string.IsNullOrEmpty(mappingModel.Title))417 {418 respondProvider = respondProvider.WithTitle(mappingModel.Title);419 }420421 if (mappingModel.Priority != null)422 {423 respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);424 }347 private ResponseMessage MappingDelete(RequestMessage requestMessage)348 {349 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));350351 if (DeleteMapping(guid))352 {353 return ResponseMessageBuilder.Create("Mapping removed", 200, guid);354 }355356 return ResponseMessageBuilder.Create("Mapping not found", 404);357 }358 #endregion Mapping/{guid}359360 #region Mappings361 private ResponseMessage MappingsSave(RequestMessage requestMessage)362 {363 SaveStaticMappings();364365 return ResponseMessageBuilder.Create("Mappings saved to disk");366 }367368 private void SaveMappingToFile(Mapping mapping, string folder = null)369 {370 if (folder == null)371 {372 folder = _fileSystemHandler.GetMappingFolder();373 }374375 if (!_fileSystemHandler.FolderExists(folder))376 {377 _fileSystemHandler.CreateFolder(folder);378 }379380 var model = MappingConverter.ToMappingModel(mapping);381 string filename = (!string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToS382383 string path = Path.Combine(folder, filename);384385 _logger.Info("Saving Mapping file {0}", filename);386387 _fileSystemHandler.WriteMappingFile(path, JsonConvert.SerializeObject(model, _settings));388 }389390 private static string SanitizeFileName(string name, char replaceChar = '_')391 {392 return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));393 }394395 private ResponseMessage MappingsGet(RequestMessage requestMessage)396 {397 var result = new List<MappingModel>();398 foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))399 {400 var model = MappingConverter.ToMappingModel(mapping);401 result.Add(model);402 }403404 return ToJson(result);405 }406407 private ResponseMessage MappingsPost(RequestMessage requestMessage)408 {409 Guid? guid;410 try411 {412 var mappingModel = DeserializeObject<MappingModel>(requestMessage);413 guid = DeserializeAndAddOrUpdateMapping(mappingModel);414 }415 catch (ArgumentException a)416 {417 _logger.Error("HttpStatusCode set to 400 {0}", a);418 return ResponseMessageBuilder.Create(a.Message, 400);419 }420 catch (Exception e)421 {422 _logger.Error("HttpStatusCode set to 500 {0}", e);423 return ResponseMessageBuilder.Create(e.ToString(), 500);424 }425426 if (mappingModel.Scenario != null)427 {428 respondProvider = respondProvider.InScenario(mappingModel.Scenario);429 respondProvider = respondProvider.WhenStateIs(mappingModel.WhenStateIs);430 respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo);431 }432433 respondProvider.RespondWith(responseBuilder);434 }435436 private ResponseMessage MappingsDelete(RequestMessage requestMessage)437 {438 ResetMappings();439440 ResetScenarios();441442 return new ResponseMessage { Body = "Mappings deleted" };443 }444 #endregion Mappings445446 #region Request/{guid}447 private ResponseMessage RequestGet(RequestMessage requestMessage)448 {449 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));450 var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid)451452 if (entry == null)453 {454 _logger.Warn("HttpStatusCode set to 404 : Request not found");455 return new ResponseMessage { StatusCode = 404, Body = "Request not found" };456 }457458 var model = ToLogEntryModel(entry);459460 return ToJson(model);461 }462463 private ResponseMessage RequestDelete(RequestMessage requestMessage)464 {465 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));466467 if (DeleteLogEntry(guid))468 return new ResponseMessage { Body = "Request removed" };469470 return new ResponseMessage { Body = "Request not found" };471 }472 #endregion Request/{guid}473474 #region Requests475 private ResponseMessage RequestsGet(RequestMessage requestMessage)476 {477 var result = LogEntries478 .Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))479 .Select(ToLogEntryModel);426 return ResponseMessageBuilder.Create("Mapping added", 201, guid);427 }428429 private Guid? DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)430 {431 Check.NotNull(mappingModel, nameof(mappingModel));432 Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));433 Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));434435 var requestBuilder = InitRequestBuilder(mappingModel.Request, true);436 if (requestBuilder == null)437 {438 return null;439 }440441 var responseBuilder = InitResponseBuilder(mappingModel.Response);442443 var respondProvider = Given(requestBuilder);444445 if (guid != null)446 {447 respondProvider = respondProvider.WithGuid(guid.Value);448 }449 else if (mappingModel.Guid != null && mappingModel.Guid != Guid.Empty)450 {451 respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);452 }453454 if (path != null)455 {456 respondProvider = respondProvider.WithPath(path);457 }458459 if (!string.IsNullOrEmpty(mappingModel.Title))460 {461 respondProvider = respondProvider.WithTitle(mappingModel.Title);462 }463464 if (mappingModel.Priority != null)465 {466 respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);467 }468469 if (mappingModel.Scenario != null)470 {471 respondProvider = respondProvider.InScenario(mappingModel.Scenario);472 respondProvider = respondProvider.WhenStateIs(mappingModel.WhenStateIs);473 respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo);474 }475476 respondProvider.RespondWith(responseBuilder);477478 return respondProvider.Guid;479 }480481 return ToJson(result);482 }483484 private LogEntryModel ToLogEntryModel(LogEntry logEntry)485 {486 return new LogEntryModel487 {488 Guid = logEntry.Guid,489 Request = new LogRequestModel490 {491 DateTime = logEntry.RequestMessage.DateTime,492 ClientIP = logEntry.RequestMessage.ClientIP,493 Path = logEntry.RequestMessage.Path,494 AbsoluteUrl = logEntry.RequestMessage.Url,495 Query = logEntry.RequestMessage.Query,496 Method = logEntry.RequestMessage.Method,497 Body = logEntry.RequestMessage.Body,498 BodyAsJson = logEntry.RequestMessage.BodyAsJson,499 BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,500 Headers = logEntry.RequestMessage.Headers,501 Cookies = logEntry.RequestMessage.Cookies,502 BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel503 {504 EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,505 CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,506 WebName = logEntry.RequestMessage.BodyEncoding.WebName507 } : null508 },509 Response = new LogResponseModel510 {511 StatusCode = logEntry.ResponseMessage.StatusCode,512 BodyDestination = logEntry.ResponseMessage.BodyDestination,513 Body = logEntry.ResponseMessage.Body,514 BodyAsJson = logEntry.ResponseMessage.BodyAsJson,515 BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,516 BodyOriginal = logEntry.ResponseMessage.BodyOriginal,517 BodyAsFile = logEntry.ResponseMessage.BodyAsFile,518 BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,519 Headers = logEntry.ResponseMessage.Headers,520 BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel521 {522 EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,523 CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,524 WebName = logEntry.ResponseMessage.BodyEncoding.WebName525 } : null526 },527 MappingGuid = logEntry.MappingGuid,528 MappingTitle = logEntry.MappingTitle,529 RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel530 {531 TotalScore = logEntry.RequestMatchResult.TotalScore,532 TotalNumber = logEntry.RequestMatchResult.TotalNumber,533 IsPerfectMatch = logEntry.RequestMatchResult.IsPerfectMatch,534 AverageTotalScore = logEntry.RequestMatchResult.AverageTotalScore,535 MatchDetails = logEntry.RequestMatchResult.MatchDetails.Select(x => new536 {537 Name = x.Key.Name.Replace("RequestMessage", string.Empty),538 Score = x.Value539 } as object).ToList()540 } : null541 };542 }481 private ResponseMessage MappingsDelete(RequestMessage requestMessage)482 {483 ResetMappings();484485 ResetScenarios();486487 return ResponseMessageBuilder.Create("Mappings deleted");488 }489 #endregion Mappings490491 #region Request/{guid}492 private ResponseMessage RequestGet(RequestMessage requestMessage)493 {494 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));495 var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid)496497 if (entry == null)498 {499 _logger.Warn("HttpStatusCode set to 404 : Request not found");500 return ResponseMessageBuilder.Create("Request not found", 404);501 }502503 var model = LogEntryMapper.Map(entry);504505 return ToJson(model);506 }507508 private ResponseMessage RequestDelete(RequestMessage requestMessage)509 {510 Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));511512 if (DeleteLogEntry(guid))513 {514 return ResponseMessageBuilder.Create("Request removed");515 }516517 return ResponseMessageBuilder.Create("Request not found", 404);518 }519 #endregion Request/{guid}520521 #region Requests522 private ResponseMessage RequestsGet(RequestMessage requestMessage)523 {524 var result = LogEntries525 .Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))526 .Select(LogEntryMapper.Map);527528 return ToJson(result);529 }530531 private ResponseMessage RequestsDelete(RequestMessage requestMessage)532 {533 ResetLogEntries();534535 return ResponseMessageBuilder.Create("Requests deleted");536 }537 #endregion Requests538539 #region Requests/find540 private ResponseMessage RequestsFind(RequestMessage requestMessage)541 {542 var requestModel = DeserializeObject<RequestModel>(requestMessage);543544 private ResponseMessage RequestsDelete(RequestMessage requestMessage)545 {546 ResetLogEntries();547548 return new ResponseMessage { Body = "Requests deleted" };549 }550 #endregion Requests551552 #region Requests/find553 private ResponseMessage RequestsFind(RequestMessage requestMessage)554 {555 var requestModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<RequestModel>(requestMessage.556557 var request = (Request)InitRequestBuilder(requestModel);558559 var dict = new Dictionary<LogEntry, RequestMatchResult>();560 foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))561 {562 var requestMatchResult = new RequestMatchResult();563 if (request.GetMatchingScore(logEntry.RequestMessage, requestMatchResult) > MatchScores.AlmostPerfect)564 {565 dict.Add(logEntry, requestMatchResult);566 }567 }568569 var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(ToLogEntryModel);570571 return ToJson(result);572 }573 #endregion Requests/find574575 #region Scenarios576 private ResponseMessage ScenariosGet(RequestMessage requestMessage)544 var request = (Request)InitRequestBuilder(requestModel, false);545546 var dict = new Dictionary<LogEntry, RequestMatchResult>();547 foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))548 {549 var requestMatchResult = new RequestMatchResult();550 if (request.GetMatchingScore(logEntry.RequestMessage, requestMatchResult) > MatchScores.AlmostPerfect)551 {552 dict.Add(logEntry, requestMatchResult);553 }554 }555556 var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(LogEntryMapper.Map);557558 return ToJson(result);559 }560 #endregion Requests/find561562 #region Scenarios563 private ResponseMessage ScenariosGet(RequestMessage requestMessage)564 {565 var scenariosStates = Scenarios.Values.Select(s => new ScenarioStateModel566 {567 Name = s.Name,568 NextState = s.NextState,569 Started = s.Started,570 Finished = s.Finished571 });572573 return ToJson(scenariosStates, true);574 }575576 private ResponseMessage ScenariosReset(RequestMessage requestMessage)577 {578 var scenarios = Scenarios.Select(s => new579 {580 Name = s.Key,581 Started = s.Value != null,582 NextState = s.Value583 });584 return ToJson(scenarios);585 }586587 private ResponseMessage ScenariosReset(RequestMessage requestMessage)588 {589 ResetScenarios();590591 return new ResponseMessage { Body = "Scenarios reset" };592 }593 #endregion594595 private IRequestBuilder InitRequestBuilder(RequestModel requestModel)596 {597 IRequestBuilder requestBuilder = Request.Create();598599 if (requestModel.ClientIP != null)600 {601 string clientIP = requestModel.ClientIP as string;602 if (clientIP != null)603 {604 requestBuilder = requestBuilder.WithClientIP(clientIP);605 }606 else607 {608 var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);609 if (clientIPModel?.Matchers != null)610 {611 requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MatcherModelMapper.Map).C612 }613 }614 }615616 if (requestModel.Path != null)617 {618 string path = requestModel.Path as string;619 if (path != null)620 {621 requestBuilder = requestBuilder.WithPath(path);622 }623 else624 {625 var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);626 if (pathModel?.Matchers != null)627 {628 requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherModelMapper.Map).Cast<629 }630 }631 }632633 if (requestModel.Url != null)634 {635 string url = requestModel.Url as string;636 if (url != null)637 {638 requestBuilder = requestBuilder.WithUrl(url);639 }640 else641 {642 var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);643 if (urlModel?.Matchers != null)644 {645 requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherModelMapper.Map).Cast<IS646 }647 }648 }649650 if (requestModel.Methods != null)651 {652 requestBuilder = requestBuilder.UsingVerb(requestModel.Methods);653 }654655 if (requestModel.Headers != null)656 {657 foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))658 {659 requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MatcherMode660 }661 }662663 if (requestModel.Cookies != null)664 {665 foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))666 {667 requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MatcherMode668 }669 }670671 if (requestModel.Params != null)672 {673 foreach (var paramModel in requestModel.Params)674 {675 requestBuilder = paramModel.Values == null ? requestBuilder.WithParam(paramModel.Name) : requestBuil676 }677 }678679 if (requestModel.Body?.Matcher != null)680 {681 var bodyMatcher = MatcherModelMapper.Map(requestModel.Body.Matcher);682 requestBuilder = requestBuilder.WithBody(bodyMatcher);683 }684685 return requestBuilder;686 }578 ResetScenarios();579580 return ResponseMessageBuilder.Create("Scenarios reset");581 }582 #endregion583584 private IRequestBuilder InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)585 {586 IRequestBuilder requestBuilder = Request.Create();587588 if (requestModel.ClientIP != null)589 {590 if (requestModel.ClientIP is string clientIP)591 {592 requestBuilder = requestBuilder.WithClientIP(clientIP);593 }594 else595 {596 var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);597 if (clientIPModel?.Matchers != null)598 {599 requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MatcherMapper.Map).Cast<I600 }601 }602 }603604 bool pathOrUrlmatchersValid = false;605 if (requestModel.Path != null)606 {607 if (requestModel.Path is string path)608 {609 requestBuilder = requestBuilder.WithPath(path);610 pathOrUrlmatchersValid = true;611 }612 else613 {614 var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);615 if (pathModel?.Matchers != null)616 {617 requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherMapper.Map).Cast<IStri618 pathOrUrlmatchersValid = true;619 }620 }621 }622 else if (requestModel.Url != null)623 {624 if (requestModel.Url is string url)625 {626 requestBuilder = requestBuilder.WithUrl(url);627 pathOrUrlmatchersValid = true;628 }629 else630 {631 var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);632 if (urlModel?.Matchers != null)633 {634 requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherMapper.Map).Cast<IString635 pathOrUrlmatchersValid = true;636 }637 }638 }639640 if (pathOrUrlRequired && !pathOrUrlmatchersValid)641 {642 _logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added.");643 return null;644 }645646 if (requestModel.Methods != null)647 {648 requestBuilder = requestBuilder.UsingMethod(requestModel.Methods);649 }650651 if (requestModel.Headers != null)652 {653 foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))654 {655 requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MatcherMapp656 }657 }658659 if (requestModel.Cookies != null)660 {661 foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))662 {663 requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MatcherMapp664 }665 }666667 if (requestModel.Params != null)668 {669 foreach (var paramModel in requestModel.Params.Where(c => c.Matchers != null))670 {671 requestBuilder = requestBuilder.WithParam(paramModel.Name, paramModel.Matchers.Select(MatcherMapper.672 }673 }674675 if (requestModel.Body?.Matcher != null)676 {677 var bodyMatcher = MatcherMapper.Map(requestModel.Body.Matcher);678 requestBuilder = requestBuilder.WithBody(bodyMatcher);679 }680681 return requestBuilder;682 }683684 private IResponseBuilder InitResponseBuilder(ResponseModel responseModel)685 {686 IResponseBuilder responseBuilder = Response.Create();687688 private IResponseBuilder InitResponseBuilder(ResponseModel responseModel)689 {690 IResponseBuilder responseBuilder = Response.Create();691692 if (responseModel.Delay > 0)693 {694 responseBuilder = responseBuilder.WithDelay(responseModel.Delay.Value);695 }696697 if (!string.IsNullOrEmpty(responseModel.ProxyUrl))698 {699 if (string.IsNullOrEmpty(responseModel.X509Certificate2ThumbprintOrSubjectName))700 {701 return responseBuilder.WithProxy(responseModel.ProxyUrl);702 }703704 return responseBuilder.WithProxy(responseModel.ProxyUrl, responseModel.X509Certificate2ThumbprintOrSubje705 }706707 if (responseModel.StatusCode.HasValue)708 {709 responseBuilder = responseBuilder.WithStatusCode(responseModel.StatusCode.Value);710 }711712 if (responseModel.Headers != null)713 {714 foreach (var entry in responseModel.Headers)715 {716 responseBuilder = entry.Value is string value ?717 responseBuilder.WithHeader(entry.Key, value) :718 responseBuilder.WithHeader(entry.Key, JsonUtils.ParseJTokenToObject<string[]>(entry.Value));719 }720 }721 else if (responseModel.HeadersRaw != null)722 {723 foreach (string headerLine in responseModel.HeadersRaw.Split(new[] { "\n", "\r\n" }, StringSplitOptions.724 {725 int indexColon = headerLine.IndexOf(":", StringComparison.Ordinal);726 string key = headerLine.Substring(0, indexColon).TrimStart(' ', '\t');727 string value = headerLine.Substring(indexColon + 1).TrimStart(' ', '\t');728 responseBuilder = responseBuilder.WithHeader(key, value);729 }730 }731732 if (responseModel.BodyAsBytes != null)733 {734 responseBuilder = responseBuilder.WithBody(responseModel.BodyAsBytes, responseModel.BodyDestination, ToE735 }736 else if (responseModel.Body != null)737 {738 responseBuilder = responseBuilder.WithBody(responseModel.Body, responseModel.BodyDestination, ToEncoding739 }740 else if (responseModel.BodyAsJson != null)688 if (responseModel.Delay > 0)689 {690 responseBuilder = responseBuilder.WithDelay(responseModel.Delay.Value);691 }692693 if (!string.IsNullOrEmpty(responseModel.ProxyUrl))694 {695 if (string.IsNullOrEmpty(responseModel.X509Certificate2ThumbprintOrSubjectName))696 {697 return responseBuilder.WithProxy(responseModel.ProxyUrl);698 }699700 return responseBuilder.WithProxy(responseModel.ProxyUrl, responseModel.X509Certificate2ThumbprintOrSubje701 }702703 if (responseModel.StatusCode.HasValue)704 {705 responseBuilder = responseBuilder.WithStatusCode(responseModel.StatusCode.Value);706 }707708 if (responseModel.Headers != null)709 {710 foreach (var entry in responseModel.Headers)711 {712 responseBuilder = entry.Value is string value ?713 responseBuilder.WithHeader(entry.Key, value) :714 responseBuilder.WithHeader(entry.Key, JsonUtils.ParseJTokenToObject<string[]>(entry.Value));715 }716 }717 else if (responseModel.HeadersRaw != null)718 {719 foreach (string headerLine in responseModel.HeadersRaw.Split(new[] { "\n", "\r\n" }, StringSplitOptions.720 {721 int indexColon = headerLine.IndexOf(":", StringComparison.Ordinal);722 string key = headerLine.Substring(0, indexColon).TrimStart(' ', '\t');723 string value = headerLine.Substring(indexColon + 1).TrimStart(' ', '\t');724 responseBuilder = responseBuilder.WithHeader(key, value);725 }726 }727728 if (responseModel.BodyAsBytes != null)729 {730 responseBuilder = responseBuilder.WithBody(responseModel.BodyAsBytes, responseModel.BodyDestination, ToE731 }732 else if (responseModel.Body != null)733 {734 responseBuilder = responseBuilder.WithBody(responseModel.Body, responseModel.BodyDestination, ToEncoding735 }736 else if (responseModel.BodyAsJson != null)737 {738 responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.Body739 }740 else if (responseModel.BodyFromBase64 != null)741 {742 responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.Body742 responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseMo743 }744 else if (responseModel.BodyFromBase64 != null)745 {746 responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseMo747 }744 else if (responseModel.BodyAsFile != null)745 {746 responseBuilder = responseBuilder.WithBodyFromFile(responseModel.BodyAsFile);747 }748749 if (responseModel.UseTransformer)749 if (responseModel.UseTransformer)750 {751 responseBuilder = responseBuilder.WithTransformer();752 }753754 return responseBuilder;755 }754 return responseBuilder;755 }756757 private ResponseMessage ToJson<T>(T result)758 {759 return new ResponseMessage760 {761 Body = JsonConvert.SerializeObject(result, _settings),762 StatusCode = 200,763 Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMoc764 };765 }757 private ResponseMessage ToJson<T>(T result, bool keepNullValues = false)758 {759 return new ResponseMessage760 {761 Body = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings),762 StatusCode = 200,763 Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMoc764 };765 }766767 private Encoding ToEncoding(EncodingModel encodingModel)768 {769 return encodingModel != null ? Encoding.GetEncoding(encodingModel.CodePage) : null;770 }771 }772}768 {769 return encodingModel != null ? Encoding.GetEncoding(encodingModel.CodePage) : null;770 }771772 private T DeserializeObject<T>(RequestMessage requestMessage)773 {774 return requestMessage.Body != null ?775 JsonConvert.DeserializeObject<T>(requestMessage.Body) :776 ((JObject)requestMessage.BodyAsJson).ToObject<T>();777 }778 }779}27 /// Gets the request logs.28 /// </summary>29 [PublicAPI]30 public IEnumerable<LogEntry> LogEntries => new ReadOnlyCollection<LogEntry>(_options.LogEntries);30 public IEnumerable<LogEntry> LogEntries => new ReadOnlyCollection<LogEntry>(_options.LogEntries);3132 /// <summary>33 /// The search log-entries based on matchers.39 {40 var results = new Dictionary<LogEntry, RequestMatchResult>();4142 foreach (var log in _options.LogEntries)42 foreach (var log in _options.LogEntries)43 {44 var requestMatchResult = new RequestMatchResult();45 foreach (var matcher in matchers)45 foreach (var matcher in matchers)46 {47 matcher.GetMatchingScore(log.RequestMessage, requestMatchResult);48 }4950 if (requestMatchResult.AverageTotalScore > MatchScores.AlmostPerfect)50 if (requestMatchResult.AverageTotalScore > MatchScores.AlmostPerfect)51 {52 results.Add(log, requestMatchResult);53 }54 }5556 return new ReadOnlyCollection<LogEntry>(results.OrderBy(x => x.Value).Select(x => x.Key).ToList());56 return new ReadOnlyCollection<LogEntry>(results.OrderBy(x => x.Value).Select(x => x.Key).ToList());57 }5859 /// <summary>61 /// </summary>62 [PublicAPI]63 public void ResetLogEntries()64 {65 _options.LogEntries.Clear();66 }64 {65 _options.LogEntries.Clear();66 }6768 /// <summary>69 /// Deletes a LogEntry.74 {75 // Check a logentry exists with the same GUID, if so, remove it.76 var existing = _options.LogEntries.FirstOrDefault(m => m.Guid == guid);77 if (existing != null)77 if (existing != null)78 {79 _options.LogEntries.Remove(existing);80 return true;86}| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor() | 1 | 0 | 100 | 100 |
1using System;2using System.Threading.Tasks;3using Newtonsoft.Json;4#if !NETSTANDARD4#if !USE_ASPNETCORE5using Microsoft.Owin;6#else7using Microsoft.AspNetCore.Http;910namespace WireMock.Owin11{12#if !NETSTANDARD12#if !USE_ASPNETCORE13 internal class GlobalExceptionMiddleware : OwinMiddleware14#else15 internal class GlobalExceptionMiddleware17 {18 private readonly WireMockMiddlewareOptions _options;1920#if !NETSTANDARD21 public GlobalExceptionMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)22 {23 _options = options;24 }20#if !USE_ASPNETCORE21 public GlobalExceptionMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)22 {23 _options = options;24 }25#else26 public GlobalExceptionMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)27 {28 Next = next;29 _options = options;30 }26 public GlobalExceptionMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)27 {28 Next = next;29 _options = options;30 }31#endif3233#if NETSTANDARD34 public RequestDelegate Next { get; }33#if USE_ASPNETCORE34 public RequestDelegate Next { get; }35#endif3637 private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();37 private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();3839#if !NETSTANDARD39#if !USE_ASPNETCORE40 public override async Task Invoke(IOwinContext ctx)41#else42 public async Task Invoke(HttpContext ctx)43#endif44 {44 {45 try46 {47 await Next?.Invoke(ctx);48 }49 catch (Exception ex)46 {47 await Next?.Invoke(ctx);48 }49 catch (Exception ex)50 {51 _options.Logger.Error("HttpStatusCode set to 500 {0}", ex);52 await _responseMapper.MapAsync(new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObjec53 }54 }52 await _responseMapper.MapAsync(ResponseMessageBuilder.Create(JsonConvert.SerializeObject(ex), 500), ctx.53 }54 }55 }56}| Class: | WireMock.Transformers.HandleBarsJsonPath |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Transformers\HandleBarsJsonPath.cs |
| Covered lines: | 46 |
| Uncovered lines: | 1 |
| Coverable lines: | 47 |
| Total lines: | 75 |
| Line coverage: | 97.8% |
| Branch coverage: | 71.4% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Register() | 0 | 0 | 1 | 1 |
| ParseArguments(...) | 0 | 0 | 0.917 | 0.6 |
| Class: | WireMock.Transformers.HandleBarsLinq |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Transformers\HandleBarsLinq.cs |
| Covered lines: | 50 |
| Uncovered lines: | 0 |
| Coverable lines: | 50 |
| Total lines: | 88 |
| Line coverage: | 100% |
| Branch coverage: | 92.8% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Register() | 0 | 0 | 1 | 1 |
| ExecuteDynamicLinq(...) | 0 | 0 | 1 | 0 |
| ParseArguments(...) | 0 | 0 | 1 | 0.9 |
| Class: | WireMock.Transformers.HandleBarsRegex |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Transformers\HandleBarsRegex.cs |
| Covered lines: | 43 |
| Uncovered lines: | 0 |
| Coverable lines: | 43 |
| Total lines: | 66 |
| Line coverage: | 100% |
| Branch coverage: | 91.6% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Register() | 0 | 0 | 1 | 1 |
| ParseArguments(...) | 0 | 0 | 1 | 1 |
| Class: | WireMock.Transformers.HandlebarsHelpers |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Transformers\HandleBarsHelpers.cs |
| Covered lines: | 5 |
| Uncovered lines: | 0 |
| Coverable lines: | 5 |
| Total lines: | 14 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Register() | 0 | 0 | 1 | 0 |
11 internal static class HttpClientHelper12 {13 public static HttpClient CreateHttpClient(string clientX509Certificate2ThumbprintOrSubjectName = null)14 {14 {15#if NETSTANDARD16 var handler = new HttpClientHandler17 {18 CheckCertificateRevocationList = false,19 SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslPro20 ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,21 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate22 };16 var handler = new HttpClientHandler17 {18 CheckCertificateRevocationList = false,19 SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslPro20 ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true,21 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate22 };23#elif NET4624 var handler = new HttpClientHandler25 {28 };29 ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;30#else31 var handler = new WebRequestHandler32 {33 ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,34 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate35 };36 ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;31 var handler = new WebRequestHandler32 {33 ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true,34 AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate35 };36 ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11;37#endif3839 if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))39 if (!string.IsNullOrEmpty(clientX509Certificate2ThumbprintOrSubjectName))40 {41 handler.ClientCertificateOptions = ClientCertificateOption.Manual;4245 }4647 // For proxy we shouldn't follow auto redirects48 handler.AllowAutoRedirect = false;48 handler.AllowAutoRedirect = false;4950 // If UseCookies enabled, httpClient ignores Cookie header51 handler.UseCookies = false;51 handler.UseCookies = false;5253 var client = new HttpClient(handler);53 var client = new HttpClient(handler);54#if NET452 || NET4655 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityPro55 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityPro56#endif57 return client;58 }57 return client;58 }5960 public static async Task<ResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] RequestMessage reques61 {62 Check.NotNull(client, nameof(client));63 Check.NotNull(requestMessage, nameof(requestMessage));61 {62 Check.NotNull(client, nameof(client));63 Check.NotNull(requestMessage, nameof(requestMessage));6465 var originalUri = new Uri(requestMessage.Url);66 var requiredUri = new Uri(url);65 var originalUri = new Uri(requestMessage.Url);66 var requiredUri = new Uri(url);6768 // Create HttpRequestMessage69 var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);69 var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);7071 // Call the URL72 var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRea72 var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRea7374 // Parse httpResponseMessage75 return await HttpResponseMessageHelper.Create(httpResponseMessage, requiredUri, originalUri);76 }75 return await HttpResponseMessageHelper.Create(httpResponseMessage, requiredUri, originalUri);76 }77 }78}11 internal static class HttpRequestMessageHelper12 {13 public static HttpRequestMessage Create(RequestMessage requestMessage, string url)14 {15 var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);14 {15 var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);1617 ContentType contentType = null;18 if (requestMessage.Headers != null && requestMessage.Headers.ContainsKey(HttpKnownHeaderNames.ContentType))19 {20 var value = requestMessage.Headers[HttpKnownHeaderNames.ContentType].FirstOrDefault();21 ContentType.TryParse(value, out contentType);22 }17 ContentType contentType = null;18 if (requestMessage.Headers != null && requestMessage.Headers.ContainsKey(HttpKnownHeaderNames.ContentType))19 {20 var value = requestMessage.Headers[HttpKnownHeaderNames.ContentType].FirstOrDefault();21 ContentType.TryParse(value, out contentType);22 }2324 // Set Body if present25 if (requestMessage.BodyAsBytes != null)25 if (requestMessage.BodyAsBytes != null)26 {27 httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);28 }29 else if (requestMessage.BodyAsJson != null)29 else if (requestMessage.BodyAsJson != null)30 {31 if (contentType != null)31 if (contentType != null)32 {33 var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");33 var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");34 httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson35 }36 else38 httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson39 }40 }41 else if (requestMessage.Body != null)42 {43 if (contentType != null)44 {45 var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");46 httpRequestMessage.Content = new StringContent(requestMessage.Body, encoding, contentType.MimeType);47 }41 else if (requestMessage.Body != null)42 {43 if (contentType != null)44 {45 var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");46 httpRequestMessage.Content = new StringContent(requestMessage.Body, encoding, contentType.MimeType);47 }48 else49 {50 httpRequestMessage.Content = new StringContent(requestMessage.Body, requestMessage.BodyEncoding);51 }52 }52 }5354 // Overwrite the host header55 httpRequestMessage.Headers.Host = new Uri(url).Authority;55 httpRequestMessage.Headers.Host = new Uri(url).Authority;5657 // Set other headers if present and if not excluded58 if (requestMessage.Headers == null || requestMessage.Headers.Count == 0)58 if (requestMessage.Headers == null || requestMessage.Headers.Count == 0)59 {60 return httpRequestMessage;61 }6263 var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };64 if (contentType != null)65 {66 excludeHeaders.Add(HttpKnownHeaderNames.ContentType);67 }63 var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };64 if (contentType != null)65 {66 excludeHeaders.Add(HttpKnownHeaderNames.ContentType);67 }6869 foreach (var header in requestMessage.Headers.Where(h => !excludeHeaders.Contains(h.Key, StringComparer.Ordi70 {69 foreach (var header in requestMessage.Headers.Where(h => !excludeHeaders.Contains(h.Key, StringComparer.Ordi70 {71 // Try to add to request headers. If failed - try to add to content headers72 if (httpRequestMessage.Headers.Contains(header.Key))72 if (httpRequestMessage.Headers.Contains(header.Key))73 {74 continue;75 }7677 if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))77 if (!httpRequestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value))78 {79 httpRequestMessage.Content.Headers.TryAddWithoutValidation(header.Key, header.Value);80 }81 }81 }8283 return httpRequestMessage;84 }83 return httpRequestMessage;84 }85 }86}| Class: | WireMock.Matchers.JsonPathMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\JSONPathMatcher.cs |
| Covered lines: | 43 |
| Uncovered lines: | 3 |
| Coverable lines: | 46 |
| Total lines: | 102 |
| Line coverage: | 93.4% |
| Branch coverage: | 90% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| IsMatch(...) | 0 | 0 | 1 | 1 |
| IsMatch(...) | 0 | 0 | 0.786 | 1 |
| GetPatterns() | 0 | 0 | 1 | 0 |
| IsMatch(...) | 0 | 0 | 1 | 0.5 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| Class: | WireMock.Util.JsonUtils |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\JsonUtils.cs |
| Covered lines: | 84 |
| Uncovered lines: | 0 |
| Coverable lines: | 84 |
| Total lines: | 147 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Class: | WireMock.Matchers.LinqMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\LinqMatcher.cs |
| Covered lines: | 36 |
| Uncovered lines: | 0 |
| Coverable lines: | 36 |
| Total lines: | 107 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Class: | WireMock.Handlers.LocalFileSystemHandler |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Handlers\LocalFileSystemHandler.cs |
| Covered lines: | 20 |
| Uncovered lines: | 5 |
| Coverable lines: | 25 |
| Total lines: | 62 |
| Line coverage: | 80% |
14 /// <value>15 /// The unique identifier.16 /// </value>17 public Guid Guid { get; set; }17 public Guid Guid { get; set; }1819 /// <summary>20 /// Gets or sets the request message.22 /// <value>23 /// The request message.24 /// </value>25 public RequestMessage RequestMessage { get; set; }25 public RequestMessage RequestMessage { get; set; }2627 /// <summary>28 /// Gets or sets the response message.30 /// <value>31 /// The response message.32 /// </value>33 public ResponseMessage ResponseMessage { get; set; }33 public ResponseMessage ResponseMessage { get; set; }3435 /// <summary>36 /// Gets or sets the request match result.38 /// <value>39 /// The request match result.40 /// </value>41 public RequestMatchResult RequestMatchResult { get; set; }41 public RequestMatchResult RequestMatchResult { get; set; }4243 /// <summary>44 /// Gets or sets the mapping unique identifier.46 /// <value>47 /// The mapping unique identifier.48 /// </value>49 public Guid? MappingGuid { get; set; }49 public Guid? MappingGuid { get; set; }5051 /// <summary>52 /// Gets or sets the mapping unique title.54 /// <value>55 /// The mapping unique title.56 /// </value>57 public string MappingTitle { get; set; }57 public string MappingTitle { get; set; }58 }59}| Class: | WireMock.Serialization.LogEntryMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Serialization\LogEntryMapper.cs |
| Covered lines: | 60 |
| Uncovered lines: | 0 |
| Coverable lines: | 60 |
| Total lines: | 72 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Map(...) | 0 | 0 | 1 | 1 |
10 /// <summary>11 /// The unique identifier.12 /// </summary>13 public Guid Guid { get; set; }13 public Guid Guid { get; set; }1415 /// <summary>16 /// The request.17 /// </summary>18 public LogRequestModel Request { get; set; }18 public LogRequestModel Request { get; set; }1920 /// <summary>21 /// The response.22 /// </summary>23 public LogResponseModel Response { get; set; }23 public LogResponseModel Response { get; set; }2425 /// <summary>26 /// The mapping unique identifier.27 /// </summary>28 public Guid? MappingGuid { get; set; }28 public Guid? MappingGuid { get; set; }2930 /// <summary>31 /// The mapping unique title.32 /// </summary>33 public string MappingTitle { get; set; }33 public string MappingTitle { get; set; }3435 /// <summary>36 /// The request match result.37 /// </summary>38 public LogRequestMatchModel RequestMatchResult { get; set; }38 public LogRequestMatchModel RequestMatchResult { get; set; }39 }40}13 /// <value>14 /// The match-score.15 /// </value>16 public double TotalScore { get; set; }16 public double TotalScore { get; set; }1718 /// <summary>19 /// Gets or sets the total number of matches.21 /// <value>22 /// The total number of matches.23 /// </value>24 public int TotalNumber { get; set; }24 public int TotalNumber { get; set; }2526 /// <summary>27 /// Gets or sets a value indicating whether this instance is perfect match.29 /// <value>30 /// <c>true</c> if this instance is perfect match; otherwise, <c>false</c>.31 /// </value>32 public bool IsPerfectMatch { get; set; }32 public bool IsPerfectMatch { get; set; }3334 /// <summary>35 /// Gets the match percentage.37 /// <value>38 /// The match percentage.39 /// </value>40 public double AverageTotalScore { get; set; }40 public double AverageTotalScore { get; set; }4142 /// <summary>43 /// Gets the match details.45 /// <value>46 /// The match details.47 /// </value>48 public IList<object> MatchDetails { get; set; }48 public IList<object> MatchDetails { get; set; }49 }50}13 /// <summary>14 /// The Client IP Address.15 /// </summary>16 public string ClientIP { get; set; }16 public string ClientIP { get; set; }1718 /// <summary>19 /// The DateTime.20 /// </summary>21 public DateTime DateTime { get; set; }21 public DateTime DateTime { get; set; }2223 /// <summary>24 /// The Path.25 /// </summary>26 public string Path { get; set; }26 public string Path { get; set; }2728 /// <summary>29 ///The absolete URL.29 /// The Absolute Path.30 /// </summary>31 public string AbsoluteUrl { get; set; }31 public string AbsolutePath { get; set; }3233 /// <summary>34 /// The query.34 /// Gets the url (relative).35 /// </summary>36 public IDictionary<string, WireMockList<string>> Query { get; set; }36 public string Url { get; set; }3738 /// <summary>39 /// The method.39 /// The absolete URL.40 /// </summary>41 public string Method { get; set; }41 public string AbsoluteUrl { get; set; }4243 /// <summary>44 /// The Headers.44 /// The query.45 /// </summary>46 public IDictionary<string, WireMockList<string>> Headers { get; set; }46 public IDictionary<string, WireMockList<string>> Query { get; set; }4748 /// <summary>49 /// Tthe Cookies.49 /// The method.50 /// </summary>51 public IDictionary<string, string> Cookies { get; set; }51 public string Method { get; set; }5253 /// <summary>54 /// The body (as string).54 /// The Headers.55 /// </summary>56 public string Body { get; set; }56 public IDictionary<string, WireMockList<string>> Headers { get; set; }5758 /// <summary>59 /// The body (as JSON object).59 /// Tthe Cookies.60 /// </summary>61 public object BodyAsJson { get; set; }61 public IDictionary<string, string> Cookies { get; set; }6263 /// <summary>64 /// The body (as bytearray).64 /// The body (as string).65 /// </summary>66 public byte[] BodyAsBytes { get; set; }66 public string Body { get; set; }6768 /// <summary>69 /// The body encoding.69 /// The body (as JSON object).70 /// </summary>71 public EncodingModel BodyEncoding { get; set; }72 }73}71 public object BodyAsJson { get; set; }7273 /// <summary>74 /// The body (as bytearray).75 /// </summary>76 public byte[] BodyAsBytes { get; set; }7778 /// <summary>79 /// The body encoding.80 /// </summary>81 public EncodingModel BodyEncoding { get; set; }82 }83}| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor() | 1 | 0 | 100 | 100 |
14 /// <summary>15 /// Gets the unique identifier.16 /// </summary>17 public Guid Guid { get; }17 public Guid Guid { get; }1819 /// <summary>20 /// Gets the unique title.21 /// </summary>22 public string Title { get; }22 public string Title { get; }2324 /// <summary>25 /// The full filename path for this mapping (only defined for static mappings).26 /// </summary>27 public string Path { get; set; }27 public string Path { get; set; }2829 /// <summary>30 /// Gets the priority.31 /// </summary>32 public int Priority { get; }32 public int Priority { get; }3334 /// <summary>35 /// Scenario.36 /// </summary>37 [CanBeNull]38 public string Scenario { get; }38 public string Scenario { get; }3940 /// <summary>41 /// Execution state condition for the current mapping.42 /// </summary>43 [CanBeNull]44 public object ExecutionConditionState { get; }44 public string ExecutionConditionState { get; }4546 /// <summary>47 /// The next state which will be signaled after the current mapping execution.48 /// In case the value is null state will not be changed.48 /// In case the value is null, state will not be changed.49 /// </summary>50 [CanBeNull]51 public object NextState { get; }51 public string NextState { get; }5253 /// <summary>54 /// The Request matcher.55 /// </summary>56 public IRequestMatcher RequestMatcher { get; }56 public IRequestMatcher RequestMatcher { get; }5758 /// <summary>59 /// The Provider.60 /// </summary>61 public IResponseProvider Provider { get; }61 public IResponseProvider Provider { get; }6263 /// <summary>64 /// Is State started ?65 /// </summary>66 public bool IsStartState => Scenario == null || Scenario != null && NextState != null && ExecutionConditionState66 public bool IsStartState => Scenario == null || Scenario != null && NextState != null && ExecutionConditionState6768 /// <summary>69 /// Initializes a new instance of the <see cref="Mapping"/> class.77 /// <param name="scenario">The scenario. [Optional]</param>78 /// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>79 /// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</par80 public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IRe81 {82 Guid = guid;83 Title = title;84 Path = path;85 RequestMatcher = requestMatcher;86 Provider = provider;87 Priority = priority;88 Scenario = scenario;89 ExecutionConditionState = executionConditionState;90 NextState = nextState;91 }80 public Mapping(Guid guid, [CanBeNull] string title, [CanBeNull] string path, IRequestMatcher requestMatcher, IRe81 {82 Guid = guid;83 Title = title;84 Path = path;85 RequestMatcher = requestMatcher;86 Provider = provider;87 Priority = priority;88 Scenario = scenario;89 ExecutionConditionState = executionConditionState;90 NextState = nextState;91 }9293 /// <summary>94 /// The response to.96 /// <param name="requestMessage">The request message.</param>97 /// <returns>The <see cref="ResponseMessage"/>.</returns>98 public async Task<ResponseMessage> ResponseToAsync(RequestMessage requestMessage)99 {100 return await Provider.ProvideResponseAsync(requestMessage);101 }99 {100 return await Provider.ProvideResponseAsync(requestMessage);101 }102103 /// <summary>104 /// Gets the RequestMatchResult based on the RequestMessage.106 /// <param name="requestMessage">The request message.</param>107 /// <param name="nextState">The Next State.</param>108 /// <returns>The <see cref="RequestMatchResult"/>.</returns>109 public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] object nextState)110 {111 var result = new RequestMatchResult();109 public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] string nextState)110 {111 var result = new RequestMatchResult();112113 RequestMatcher.GetMatchingScore(requestMessage, result);113 RequestMatcher.GetMatchingScore(requestMessage, result);114115 // Only check state if Scenario is defined116 if (Scenario != null)117 {118 var matcher = new RequestMessageScenarioAndStateMatcher(nextState, ExecutionConditionState);119 matcher.GetMatchingScore(requestMessage, result);116 if (Scenario != null)117 {118 var matcher = new RequestMessageScenarioAndStateMatcher(nextState, ExecutionConditionState);119 matcher.GetMatchingScore(requestMessage, result);120 //// If ExecutionConditionState is null, this means that request is the start from a scenario. So just r121 //if (ExecutionConditionState != null)122 //{124 // var matcher = new RequestMessageScenarioAndStateMatcher(nextState, ExecutionConditionState);125 // matcher.GetMatchingScore(requestMessage, result);126 //}127 }127 }128129 return result;130 }129 return result;130 }131132 /// <summary>133 /// Gets a value indicating whether this mapping is an Admin Interface.135 /// <value>136 /// <c>true</c> if this mapping is an Admin Interface; otherwise, <c>false</c>.137 /// </value>138 public bool IsAdminInterface => Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider 138 public bool IsAdminInterface => Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider 139 }140}| Class: | WireMock.Serialization.MappingConverter |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Serialization\MappingConverter.cs |
| Covered lines: | 87 |
| Uncovered lines: | 29 |
| Coverable lines: | 116 |
| Total lines: | 142 |
| Line coverage: | 75% |
| Branch coverage: | 48.5% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| ToMappingModel(...) | 0 | 0 | 0.788 | 0.516 |
| Map(...) | 0 | 0 | 0.417 | 0.25 |
10 /// <summary>11 /// Gets or sets the unique identifier.12 /// </summary>13 public Guid? Guid { get; set; }13 public Guid? Guid { get; set; }1415 /// <summary>16 /// The unique title.17 /// </summary>18 public string Title { get; set; }18 public string Title { get; set; }1920 /// <summary>21 /// The priority.22 /// </summary>23 public int? Priority { get; set; }23 public int? Priority { get; set; }2425 /// <summary>26 /// The Scenario.27 /// </summary>28 public string Scenario { get; set; }28 public string Scenario { get; set; }2930 /// <summary>31 /// Execution state condition for the current mapping.32 /// </summary>33 public object WhenStateIs { get; set; }33 public string WhenStateIs { get; set; }3435 /// <summary>36 /// The next state which will be signaled after the current mapping execution.37 /// In case the value is null state will not be changed.38 /// </summary>39 public object SetStateTo { get; set; }39 public string SetStateTo { get; set; }4041 /// <summary>42 /// The request.43 /// </summary>44 public RequestModel Request { get; set; }44 public RequestModel Request { get; set; }4546 /// <summary>47 /// The response.48 /// </summary>49 public ResponseModel Response { get; set; }49 public ResponseModel Response { get; set; }50 }51}| Class: | WireMock.Matchers.MatchBehaviourHelper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\MatchBehaviourHelper.cs |
| Covered lines: | 6 |
| Uncovered lines: | 0 |
| Coverable lines: | 6 |
| Total lines: | 27 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Convert(...) | 0 | 0 | 1 | 1 |
34 /// <param name="value">if set to <c>true</c> [value].</param>35 /// <returns>score</returns>36 public static double ToScore(bool value)37 {38 return value ? Perfect : Mismatch;39 }37 {38 return value ? Perfect : Mismatch;39 }4041 /// <summary>42 /// Calculates the score from multiple funcs.44 /// <param name="values">The values.</param>45 /// <returns>average score</returns>46 public static double ToScore(IEnumerable<bool> values)47 {48 return values.Any() ? values.Select(ToScore).Average() : Mismatch;49 }47 {48 return values.Any() ? values.Select(ToScore).Average() : Mismatch;49 }5051 /// <summary>52 /// Calculates the score from multiple funcs.55 /// <returns>average score</returns>56 public static double ToScore(IEnumerable<double> values)57 {58 return values.Any() ? values.Average() : Mismatch;58 return values.Any() ? values.Average() : Mismatch;59 }60 }61}| Class: | WireMock.Serialization.MatcherMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Serialization\MatcherMapper.cs |
| Covered lines: | 43 |
| Uncovered lines: | 3 |
| Coverable lines: | 46 |
| Total lines: | 96 |
| Line coverage: | 93.4% |
| Branch coverage: | 86.7% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Map(...) | 0 | 0 | 0.875 | 0.86 |
| Map(...) | 0 | 0 | 1 | 1 |
| Map(...) | 0 | 0 | 1 | 0.857 |
1using System;2using System.Collections.Generic;3// using System.IO;4using System.Linq;5// using System.Text;6using System.Threading.Tasks;7using WireMock.Util;8#if !NETSTANDARD9using Microsoft.Owin;10#else11using Microsoft.AspNetCore.Http;12using Microsoft.AspNetCore.Http.Extensions;13#endif1415namespace WireMock.Owin16{17 /// <summary>18 /// OwinRequestMapper19 /// </summary>20 internal class OwinRequestMapper21 {22 /// <summary>23 /// MapAsync IOwinRequest to RequestMessage24 /// </summary>25 /// <param name="request"></param>26 /// <returns></returns>27 public async Task<RequestMessage> MapAsync(28#if !NETSTANDARD29 IOwinRequest request30#else31 HttpRequest request32#endif33 )34 {35#if !NETSTANDARD36 Uri url = request.Uri;37 string clientIP = request.RemoteIpAddress;38#else39 Uri url = new Uri(request.GetEncodedUrl());40 var connection = request.HttpContext.Connection;41 string clientIP = connection.RemoteIpAddress.IsIPv4MappedToIPv642 ? connection.RemoteIpAddress.MapToIPv4().ToString()43 : connection.RemoteIpAddress.ToString();44#endif45 string method = request.Method;4647 Dictionary<string, string[]> headers = null;48 if (request.Headers.Any())49 {50 headers = new Dictionary<string, string[]>();51 foreach (var header in request.Headers)52 {53 headers.Add(header.Key, header.Value);54 }55 }5657 IDictionary<string, string> cookies = null;58 if (request.Cookies.Any())59 {60 cookies = new Dictionary<string, string>();61 foreach (var cookie in request.Cookies)62 {63 cookies.Add(cookie.Key, cookie.Value);64 }65 }6667 BodyData body = null;68 if (request.Body != null && ShouldParseBody(method))69 {70 body = await BodyParser.Parse(request.Body, request.ContentType);71 }7273 return new RequestMessage(url, method, clientIP, body, headers, cookies) { DateTime = DateTime.Now };74 }7576 private bool ShouldParseBody(string method)77 {78 /*79 HEAD - No defined body semantics.80 GET - No defined body semantics.81 PUT - Body supported.82 POST - Body supported.83 DELETE - No defined body semantics.84 TRACE - Body not supported.85 OPTIONS - Body supported but no semantics on usage (maybe in the future).86 CONNECT - No defined body semantics87 PATCH - Body supported.88 */89 return new[] { "PUT", "POST", "OPTIONS", "PATCH" }.Contains(method.ToUpper());90 }91 }92}3using System.Linq;4using System.Threading.Tasks;5using WireMock.Util;6#if !USE_ASPNETCORE7using Microsoft.Owin;8#else9using Microsoft.AspNetCore.Http;10using Microsoft.AspNetCore.Http.Extensions;11#endif1213namespace WireMock.Owin14{15 /// <summary>16 /// OwinRequestMapper17 /// </summary>18 internal class OwinRequestMapper19 {20 /// <summary>21 /// MapAsync IOwinRequest to RequestMessage22 /// </summary>23 /// <param name="request"></param>24 /// <returns></returns>25 public async Task<RequestMessage> MapAsync(26#if !USE_ASPNETCORE27 IOwinRequest request28#else29 HttpRequest request30#endif31 )32 {33#if !USE_ASPNETCORE34 var urldetails = UrlUtils.Parse(request.Uri, request.PathBase);35 string clientIP = request.RemoteIpAddress;36#else37 var urldetails = UrlUtils.Parse(new Uri(request.GetEncodedUrl()), request.PathBase);38 var connection = request.HttpContext.Connection;39 string clientIP = connection.RemoteIpAddress.IsIPv4MappedToIPv640 ? connection.RemoteIpAddress.MapToIPv4().ToString()41 : connection.RemoteIpAddress.ToString();42#endif43 string method = request.Method;4445 Dictionary<string, string[]> headers = null;46 if (request.Headers.Any())47 {48 headers = new Dictionary<string, string[]>();49 foreach (var header in request.Headers)50 {51 headers.Add(header.Key, header.Value);52 }53 }5455 IDictionary<string, string> cookies = null;56 if (request.Cookies.Any())57 {58 cookies = new Dictionary<string, string>();59 foreach (var cookie in request.Cookies)60 {61 cookies.Add(cookie.Key, cookie.Value);62 }63 }6465 BodyData body = null;66 if (request.Body != null && ShouldParseBody(method))67 {68 body = await BodyParser.Parse(request.Body, request.ContentType);69 }7071 return new RequestMessage(urldetails, method, clientIP, body, headers, cookies) { DateTime = DateTime.Now };72 }7374 private bool ShouldParseBody(string method)75 {76 /*77 HEAD - No defined body semantics.78 GET - No defined body semantics.79 PUT - Body supported.80 POST - Body supported.81 DELETE - No defined body semantics.82 TRACE - Body not supported.83 OPTIONS - Body supported but no semantics on usage (maybe in the future).84 CONNECT - No defined body semantics85 PATCH - Body supported.86 */87 return new[] { "PUT", "POST", "OPTIONS", "PATCH" }.Contains(method.ToUpper());88 }89 }90}| Class: | WireMock.Owin.OwinResponseMapper |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Owin\OwinResponseMapper.cs |
| Covered lines: | 42 |
| Uncovered lines: | 5 |
| Coverable lines: | 47 |
| Total lines: | 114 |
| Line coverage: | 89.3% |
| Branch coverage: | 80.7% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| SetResponseHeaders(...) | 0 | 0 | 1 | 0.833 |
| .ctor() | 0 | 0 | 1 | 0 |
| .cctor() | 0 | 0 | 1 | 0 |
| MapAsync() | 0 | 0 | 0.833 | 0.8 |
| Class: | WireMock.Admin.Mappings.PathModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\PathModel.cs |
| Covered lines: | 1 |
| Uncovered lines: | 0 |
| Coverable lines: | 1 |
| Total lines: | 13 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor() | 1 | 0 | 100 | 100 |
| Line coverage: | 0% |
9 {10 /// <inheritdoc cref="IProxyAndRecordSettings.Url"/>11 [PublicAPI]12 public string Url { get; set; }12 public string Url { get; set; }1314 /// <inheritdoc cref="IProxyAndRecordSettings.SaveMapping"/>15 [PublicAPI]16 public bool SaveMapping { get; set; } = true;16 public bool SaveMapping { get; set; } = true;1718 /// <inheritdoc cref="IProxyAndRecordSettings.SaveMappingToFile"/>19 [PublicAPI]20 public bool SaveMappingToFile { get; set; } = true;20 public bool SaveMappingToFile { get; set; } = true;2122 /// <inheritdoc cref="IProxyAndRecordSettings.ClientX509Certificate2ThumbprintOrSubjectName"/>23 [PublicAPI]24 public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }24 public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }2526 /// <inheritdoc cref="IProxyAndRecordSettings.BlackListedHeaders"/>27 [PublicAPI]28 public string[] BlackListedHeaders { get; set; }28 public string[] BlackListedHeaders { get; set; }29 }30}11 private readonly Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>> _responseMessageFunc;12 private readonly IProxyAndRecordSettings _settings;1314 public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>>15 {16 Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));17 Check.NotNull(settings, nameof(settings));14 public ProxyAsyncResponseProvider([NotNull] Func<RequestMessage, IProxyAndRecordSettings, Task<ResponseMessage>>15 {16 Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));17 Check.NotNull(settings, nameof(settings));1819 _responseMessageFunc = responseMessageFunc;20 _settings = settings;21 }19 _responseMessageFunc = responseMessageFunc;20 _settings = settings;21 }2223 public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)24 {25 return _responseMessageFunc(requestMessage, _settings);26 }24 {25 return _responseMessageFunc(requestMessage, _settings);26 }27 }28}| Class: | WireMock.Matchers.RegexMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\RegexMatcher.cs |
| Covered lines: | 38 |
| Uncovered lines: | 3 |
| Coverable lines: | 41 |
| Total lines: | 104 |
| Line coverage: | 92.6% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| IsMatch(...) | 0 | 0 | 0.769 | 1 |
| GetPatterns() | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 1 |
| Class: | WireMock.Utils.RegexUtils |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\RegexUtils.cs |
| Covered lines: | 12 |
| Uncovered lines: | 0 |
| Coverable lines: | 12 |
| Total lines: | 24 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| GetNamedGroups(...) | 0 | 0 | 1 | 1 |
21 /// </summary>22 /// <returns>The <see cref="IRequestBuilder"/>.</returns>23 public static IRequestBuilder Create()24 {25 return new Request(new List<IRequestMatcher>());26 }24 {25 return new Request(new List<IRequestMatcher>());26 }2728 /// <summary>29 /// Initializes a new instance of the <see cref="Request"/> class.30 /// </summary>31 /// <param name="requestMatchers">The request matchers.</param>32 private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)33 {34 _requestMatchers = requestMatchers;35 }32 private Request(IList<IRequestMatcher> requestMatchers) : base(requestMatchers)33 {34 _requestMatchers = requestMatchers;35 }3637 /// <summary>38 /// Gets the request message matchers.40 /// <typeparam name="T">Type of IRequestMatcher</typeparam>41 /// <returns>A List{T}</returns>42 public IList<T> GetRequestMessageMatchers<T>() where T : IRequestMatcher43 {44 return new ReadOnlyCollection<T>(_requestMatchers.Where(rm => rm is T).Cast<T>().ToList());45 }43 {44 return new ReadOnlyCollection<T>(_requestMatchers.Where(rm => rm is T).Cast<T>().ToList());45 }4647 /// <summary>48 /// Gets the request message matcher.50 /// <typeparam name="T">Type of IRequestMatcher</typeparam>51 /// <returns>A RequestMatcher</returns>52 public T GetRequestMessageMatcher<T>() where T : IRequestMatcher53 {54 return _requestMatchers.Where(rm => rm is T).Cast<T>().FirstOrDefault();55 }53 {54 return _requestMatchers.Where(rm => rm is T).Cast<T>().FirstOrDefault();55 }5657 /// <summary>58 /// The with clientIP.59 /// </summary>60 /// <param name="matchers">The matchers.</param>61 /// <returns>The <see cref="IRequestBuilder"/>.</returns>62 public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)63 {64 Check.NotNullOrEmpty(matchers, nameof(matchers));57 /// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(IStringMatcher[])"/>58 public IRequestBuilder WithClientIP(params IStringMatcher[] matchers)59 {60 Check.NotNullOrEmpty(matchers, nameof(matchers));6162 _requestMatchers.Add(new RequestMessageClientIPMatcher(matchers));63 return this;64 }6566 _requestMatchers.Add(new RequestMessageClientIPMatcher(matchers));67 return this;68 }6970 /// <summary>71 /// The with clientIP.72 /// </summary>73 /// <param name="clientIPs">The ClientIPs.</param>74 /// <returns>The <see cref="IRequestBuilder"/>.</returns>75 public IRequestBuilder WithClientIP(params string[] clientIPs)76 {77 Check.NotNullOrEmpty(clientIPs, nameof(clientIPs));7879 _requestMatchers.Add(new RequestMessageClientIPMatcher(clientIPs));80 return this;81 }8283 /// <summary>84 /// The with clientIP.85 /// </summary>86 /// <param name="funcs">The clientIP funcs.</param>87 /// <returns>The <see cref="IRequestBuilder"/>.</returns>88 public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)89 {90 Check.NotNullOrEmpty(funcs, nameof(funcs));9192 _requestMatchers.Add(new RequestMessageClientIPMatcher(funcs));93 return this;94 }9596 /// <summary>97 /// The with path.98 /// </summary>99 /// <param name="matchers">The matchers.</param>100 /// <returns>The <see cref="IRequestBuilder"/>.</returns>101 public IRequestBuilder WithPath(params IStringMatcher[] matchers)102 {103 Check.NotNullOrEmpty(matchers, nameof(matchers));66 /// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(string[])"/>67 public IRequestBuilder WithClientIP(params string[] clientIPs)68 {69 return WithClientIP(MatchBehaviour.AcceptOnMatch, clientIPs);70 }7172 /// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(string[])"/>73 public IRequestBuilder WithClientIP(MatchBehaviour matchBehaviour, params string[] clientIPs)74 {75 Check.NotNullOrEmpty(clientIPs, nameof(clientIPs));7677 _requestMatchers.Add(new RequestMessageClientIPMatcher(matchBehaviour, clientIPs));78 return this;79 }8081 /// <inheritdoc cref="IClientIPRequestBuilder.WithClientIP(Func{string, bool}[])"/>82 public IRequestBuilder WithClientIP(params Func<string, bool>[] funcs)83 {84 Check.NotNullOrEmpty(funcs, nameof(funcs));8586 _requestMatchers.Add(new RequestMessageClientIPMatcher(funcs));87 return this;88 }8990 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(IStringMatcher[])"/>91 public IRequestBuilder WithPath(params IStringMatcher[] matchers)92 {93 Check.NotNullOrEmpty(matchers, nameof(matchers));9495 _requestMatchers.Add(new RequestMessagePathMatcher(matchers));96 return this;97 }9899 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(string[])"/>100 public IRequestBuilder WithPath(params string[] paths)101 {102 return WithPath(MatchBehaviour.AcceptOnMatch, paths);103 }104105 _requestMatchers.Add(new RequestMessagePathMatcher(matchers));106 return this;107 }108109 /// <summary>110 /// The with path.111 /// </summary>112 /// <param name="paths">The paths.</param>113 /// <returns>The <see cref="IRequestBuilder"/>.</returns>114 public IRequestBuilder WithPath(params string[] paths)115 {116 Check.NotNullOrEmpty(paths, nameof(paths));117118 _requestMatchers.Add(new RequestMessagePathMatcher(paths));119 return this;120 }121122 /// <summary>123 /// The with path.124 /// </summary>125 /// <param name="funcs">The path func.</param>126 /// <returns>The <see cref="IRequestBuilder"/>.</returns>127 public IRequestBuilder WithPath(params Func<string, bool>[] funcs)128 {129 Check.NotNullOrEmpty(funcs, nameof(funcs));130131 _requestMatchers.Add(new RequestMessagePathMatcher(funcs));132 return this;133 }134135 /// <summary>136 /// The with url.137 /// </summary>138 /// <param name="matchers">The matchers.</param>139 /// <returns>The <see cref="IRequestBuilder"/>.</returns>140 public IRequestBuilder WithUrl(params IStringMatcher[] matchers)141 {142 Check.NotNullOrEmpty(matchers, nameof(matchers));143144 _requestMatchers.Add(new RequestMessageUrlMatcher(matchers));145 return this;146 }147148 /// <summary>149 /// The with url.150 /// </summary>151 /// <param name="urls">The urls.</param>152 /// <returns>The <see cref="IRequestBuilder"/>.</returns>153 public IRequestBuilder WithUrl(params string[] urls)154 {155 Check.NotNullOrEmpty(urls, nameof(urls));156157 _requestMatchers.Add(new RequestMessageUrlMatcher(urls));158 return this;159 }160161 /// <summary>162 /// The with url.163 /// </summary>164 /// <param name="funcs">The url func.</param>165 /// <returns>The <see cref="IRequestBuilder"/>.</returns>166 public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)167 {168 Check.NotNullOrEmpty(funcs, nameof(funcs));105 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(MatchBehaviour, string[])"/>106 public IRequestBuilder WithPath(MatchBehaviour matchBehaviour, params string[] paths)107 {108 Check.NotNullOrEmpty(paths, nameof(paths));109110 _requestMatchers.Add(new RequestMessagePathMatcher(matchBehaviour, paths));111 return this;112 }113114 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithPath(Func{string, bool}[])"/>115 public IRequestBuilder WithPath(params Func<string, bool>[] funcs)116 {117 Check.NotNullOrEmpty(funcs, nameof(funcs));118119 _requestMatchers.Add(new RequestMessagePathMatcher(funcs));120 return this;121 }122123 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(IStringMatcher[])"/>124 public IRequestBuilder WithUrl(params IStringMatcher[] matchers)125 {126 Check.NotNullOrEmpty(matchers, nameof(matchers));127128 _requestMatchers.Add(new RequestMessageUrlMatcher(matchers));129 return this;130 }131132 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(string[])"/>133 public IRequestBuilder WithUrl(params string[] urls)134 {135 return WithUrl(MatchBehaviour.AcceptOnMatch, urls);136 }137138 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(MatchBehaviour, string[])"/>139 public IRequestBuilder WithUrl(MatchBehaviour matchBehaviour, params string[] urls)140 {141 Check.NotNullOrEmpty(urls, nameof(urls));142143 _requestMatchers.Add(new RequestMessageUrlMatcher(matchBehaviour, urls));144 return this;145 }146147 /// <inheritdoc cref="IUrlAndPathRequestBuilder.WithUrl(Func{string, bool}[])"/>148 public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)149 {150 Check.NotNullOrEmpty(funcs, nameof(funcs));151152 _requestMatchers.Add(new RequestMessageUrlMatcher(funcs));153 return this;154 }155156 /// <inheritdoc cref="IMethodRequestBuilder.UsingDelete(MatchBehaviour)"/>157 public IRequestBuilder UsingDelete(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)158 {159 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "delete"));160 return this;161 }162163 /// <inheritdoc cref="IMethodRequestBuilder.UsingGet(MatchBehaviour)"/>164 public IRequestBuilder UsingGet(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)165 {166 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "get"));167 return this;168 }169170 _requestMatchers.Add(new RequestMessageUrlMatcher(funcs));171 return this;172 }173174 /// <inheritdoc cref="IMethodRequestBuilder.UsingDelete"/>175 public IRequestBuilder UsingDelete()176 {177 _requestMatchers.Add(new RequestMessageMethodMatcher("delete"));178 return this;179 }180181 /// <inheritdoc cref="IMethodRequestBuilder.UsingGet"/>182 public IRequestBuilder UsingGet()183 {184 _requestMatchers.Add(new RequestMessageMethodMatcher("get"));185 return this;186 }187188 /// <inheritdoc cref="IMethodRequestBuilder.UsingHead"/>189 public IRequestBuilder UsingHead()190 {191 _requestMatchers.Add(new RequestMessageMethodMatcher("head"));192 return this;193 }194195 /// <inheritdoc cref="IMethodRequestBuilder.UsingPost"/>196 public IRequestBuilder UsingPost()197 {198 _requestMatchers.Add(new RequestMessageMethodMatcher("post"));199 return this;200 }201202 /// <inheritdoc cref="IMethodRequestBuilder.UsingPatch"/>203 public IRequestBuilder UsingPatch()204 {205 _requestMatchers.Add(new RequestMessageMethodMatcher("patch"));206 return this;207 }208209 /// <inheritdoc cref="IMethodRequestBuilder.UsingPut"/>210 public IRequestBuilder UsingPut()211 {212 _requestMatchers.Add(new RequestMessageMethodMatcher("put"));213 return this;214 }170 /// <inheritdoc cref="IMethodRequestBuilder.UsingHead(MatchBehaviour)"/>171 public IRequestBuilder UsingHead(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)172 {173 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "head"));174 return this;175 }176177 /// <inheritdoc cref="IMethodRequestBuilder.UsingPost(MatchBehaviour)"/>178 public IRequestBuilder UsingPost(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)179 {180 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "post"));181 return this;182 }183184 /// <inheritdoc cref="IMethodRequestBuilder.UsingPatch(MatchBehaviour)"/>185 public IRequestBuilder UsingPatch(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)186 {187 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "patch"));188 return this;189 }190191 /// <inheritdoc cref="IMethodRequestBuilder.UsingPut(MatchBehaviour)"/>192 public IRequestBuilder UsingPut(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)193 {194 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, "put"));195 return this;196 }197198 /// <inheritdoc cref="IMethodRequestBuilder.UsingAnyMethod"/>199 public IRequestBuilder UsingAnyMethod()200 {201 var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();202 foreach (var matcher in matchers)203 {204 _requestMatchers.Remove(matcher);205 }206207 return this;208 }209210 /// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>211 public IRequestBuilder UsingAnyVerb()212 {213 return UsingAnyMethod();214 }215216 /// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>217 public IRequestBuilder UsingAnyVerb()218 {219 var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();220 foreach (var matcher in matchers)221 {222 _requestMatchers.Remove(matcher);223 }224225 return this;226 }216 /// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(string[])"/>217 public IRequestBuilder UsingMethod(params string[] methods)218 {219 return UsingMethod(MatchBehaviour.AcceptOnMatch, methods);220 }221222 /// <inheritdoc cref="IMethodRequestBuilder.UsingVerb(string[])"/>223 public IRequestBuilder UsingVerb(params string[] verbs)224 {225 return UsingMethod(verbs);226 }227228 /// <inheritdoc cref="IMethodRequestBuilder.UsingVerb"/>229 public IRequestBuilder UsingVerb(params string[] verbs)230 {231 Check.NotNullOrEmpty(verbs, nameof(verbs));228 /// <inheritdoc cref="IMethodRequestBuilder.UsingMethod(MatchBehaviour, string[])"/>229 public IRequestBuilder UsingMethod(MatchBehaviour matchBehaviour, params string[] methods)230 {231 Check.NotNullOrEmpty(methods, nameof(methods));232233 _requestMatchers.Add(new RequestMessageMethodMatcher(verbs));234 return this;235 }233 _requestMatchers.Add(new RequestMessageMethodMatcher(matchBehaviour, methods));234 return this;235 }236237 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(string)"/>238 public IRequestBuilder WithBody(string body)237 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(string, MatchBehaviour)"/>238 public IRequestBuilder WithBody(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)239 {240 _requestMatchers.Add(new RequestMessageBodyMatcher(body));240 _requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));241 return this;242 }243244 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[])"/>245 public IRequestBuilder WithBody(byte[] body)244 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(byte[], MatchBehaviour)"/>245 public IRequestBuilder WithBody(byte[] body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)246 {247 _requestMatchers.Add(new RequestMessageBodyMatcher(body));247 _requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));248 return this;249 }250251 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(object)"/>252 public IRequestBuilder WithBody(object body)251 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(object, MatchBehaviour)"/>252 public IRequestBuilder WithBody(object body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)253 {254 _requestMatchers.Add(new RequestMessageBodyMatcher(body));254 _requestMatchers.Add(new RequestMessageBodyMatcher(matchBehaviour, body));255 return this;256 }257258 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(IMatcher)"/>259 public IRequestBuilder WithBody(IMatcher matcher)260 {261 Check.NotNull(matcher, nameof(matcher));260 {261 Check.NotNull(matcher, nameof(matcher));262263 _requestMatchers.Add(new RequestMessageBodyMatcher(matcher));264 return this;265 }263 _requestMatchers.Add(new RequestMessageBodyMatcher(matcher));264 return this;265 }266267 /// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{string, bool})"/>268 public IRequestBuilder WithBody(Func<string, bool> func)291 return this;292 }293294 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(string)"/>295 public IRequestBuilder WithParam(string key)294 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour)"/>295 public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)296 {297 Check.NotNull(key, nameof(key));298299 _requestMatchers.Add(new RequestMessageParamMatcher(key));299 _requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key));300 return this;301 }302303 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, string[])"/>304 public IRequestBuilder WithParam(string key, params string[] values)305 {306 Check.NotNull(key, nameof(key));307308 _requestMatchers.Add(new RequestMessageParamMatcher(key, values));309 return this;310 }311312 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(Func{IDictionary{string, WireMockList{string}}, bool}[])"/313 public IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)314 {315 Check.NotNullOrEmpty(funcs, nameof(funcs));316317 _requestMatchers.Add(new RequestMessageParamMatcher(funcs));318 return this;319 }320321 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string,bool)"/>322 public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)323 {324 Check.NotNull(name, nameof(name));325 Check.NotNull(pattern, nameof(pattern));326327 _requestMatchers.Add(new RequestMessageHeaderMatcher(name, pattern, ignoreCase));328 return this;329 }330331 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string[],bool)"/>332 public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true)333 {334 Check.NotNull(name, nameof(name));335 Check.NotNull(patterns, nameof(patterns));336337 _requestMatchers.Add(new RequestMessageHeaderMatcher(name, patterns, ignoreCase));338 return this;339 }340341 /// <summary>342 /// With header.343 /// </summary>344 /// <param name="name">The name.</param>345 /// <param name="matchers">The matchers.</param>346 /// <returns>The <see cref="IRequestBuilder"/>.</returns>347 public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)348 {349 Check.NotNull(name, nameof(name));350 Check.NotNullOrEmpty(matchers, nameof(matchers));351352 _requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));353 return this;354 }355356 /// <summary>357 /// With header.358 /// </summary>359 /// <param name="funcs">The funcs.</param>360 /// <returns>The <see cref="IRequestBuilder"/>.</returns>361 public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)362 {363 Check.NotNullOrEmpty(funcs, nameof(funcs));364365 _requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));366 return this;367 }368369 /// <summary>370 /// With cookie.371 /// </summary>372 /// <param name="name">The name.</param>373 /// <param name="pattern">The pattern.</param>374 /// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>375 /// <returns>The <see cref="IRequestBuilder"/>.</returns>376 public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true)377 {378 _requestMatchers.Add(new RequestMessageCookieMatcher(name, pattern, ignoreCase));379 return this;380 }381382 /// <summary>383 /// With cookie.384 /// </summary>385 /// <param name="name">The name.</param>386 /// <param name="matchers">The matchers.</param>387 /// <returns>The <see cref="IRequestBuilder"/>.</returns>388 public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)389 {390 Check.NotNullOrEmpty(matchers, nameof(matchers));391392 _requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));393 return this;394 }395396 /// <summary>397 /// With header.398 /// </summary>399 /// <param name="funcs">The funcs.</param>400 /// <returns>The <see cref="IRequestBuilder"/>.</returns>401 public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)306 return WithParam(key, MatchBehaviour.AcceptOnMatch, values);307 }308309 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, IStringMatcher[])"/>310 public IRequestBuilder WithParam(string key, params IStringMatcher[] matchers)311 {312 return WithParam(key, MatchBehaviour.AcceptOnMatch, matchers);313 }314315 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour, string[])"/>316 public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params string[] values)317 {318 Check.NotNull(key, nameof(key));319320 _requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, values));321 return this;322 }323324 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(string, MatchBehaviour, IStringMatcher[])"/>325 public IRequestBuilder WithParam(string key, MatchBehaviour matchBehaviour, params IStringMatcher[] matchers)326 {327 Check.NotNull(key, nameof(key));328329 _requestMatchers.Add(new RequestMessageParamMatcher(matchBehaviour, key, matchers));330 return this;331 }332333 /// <inheritdoc cref="IParamsRequestBuilder.WithParam(Func{IDictionary{string, WireMockList{string}}, bool}[])"/334 public IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)335 {336 Check.NotNullOrEmpty(funcs, nameof(funcs));337338 _requestMatchers.Add(new RequestMessageParamMatcher(funcs));339 return this;340 }341342 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, MatchBehaviour)"/>343 public IRequestBuilder WithHeader(string name, string pattern, MatchBehaviour matchBehaviour)344 {345 return WithHeader(name, pattern, true, matchBehaviour);346 }347348 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string, bool, MatchBehaviour)"/>349 public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehav350 {351 Check.NotNull(name, nameof(name));352 Check.NotNull(pattern, nameof(pattern));353354 _requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, pattern, ignoreCase));355 return this;356 }357358 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], MatchBehaviour)"/>359 public IRequestBuilder WithHeader(string name, string[] patterns, MatchBehaviour matchBehaviour)360 {361 return WithHeader(name, patterns, true, matchBehaviour);362 }363364 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, string[], bool, MatchBehaviour)"/>365 public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true, MatchBehaviour matchBe366 {367 Check.NotNull(name, nameof(name));368 Check.NotNull(patterns, nameof(patterns));369370 _requestMatchers.Add(new RequestMessageHeaderMatcher(matchBehaviour, name, patterns, ignoreCase));371 return this;372 }373374 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string, IStringMatcher[])"/>375 public IRequestBuilder WithHeader(string name, params IStringMatcher[] matchers)376 {377 Check.NotNull(name, nameof(name));378 Check.NotNullOrEmpty(matchers, nameof(matchers));379380 _requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));381 return this;382 }383384 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(Func{IDictionary{string, string[]}, bool}[])"/385 public IRequestBuilder WithHeader(params Func<IDictionary<string, string[]>, bool>[] funcs)386 {387 Check.NotNullOrEmpty(funcs, nameof(funcs));388389 _requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));390 return this;391 }392393 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, string, bool, MatchBehaviour)"/>394 public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true, MatchBehaviour matchBehav395 {396 _requestMatchers.Add(new RequestMessageCookieMatcher(matchBehaviour, name, pattern, ignoreCase));397 return this;398 }399400 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(string, IStringMatcher[])"/>401 public IRequestBuilder WithCookie(string name, params IStringMatcher[] matchers)402 {403 Check.NotNullOrEmpty(funcs, nameof(funcs));403 Check.NotNullOrEmpty(matchers, nameof(matchers));404405 _requestMatchers.Add(new RequestMessageCookieMatcher(funcs));405 _requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));406 return this;407 }408 }409}408409 /// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithCookie(Func{IDictionary{string, string}, bool}[])"/>410 public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)411 {412 Check.NotNullOrEmpty(funcs, nameof(funcs));413414 _requestMatchers.Add(new RequestMessageCookieMatcher(funcs));415 return this;416 }417 }418}14 /// <value>15 /// The match-score.16 /// </value>17 public double TotalScore { get; private set; }17 public double TotalScore { get; private set; }1819 /// <summary>20 /// Gets or sets the total number of matches.22 /// <value>23 /// The total number of matches.24 /// </value>25 public int TotalNumber { get; private set; }25 public int TotalNumber { get; private set; }2627 /// <summary>28 /// Gets or sets a value indicating whether this instance is perfect match.30 /// <value>31 /// <c>true</c> if this instance is perfect match; otherwise, <c>false</c>.32 /// </value>33 public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance;33 public bool IsPerfectMatch => Math.Abs(TotalScore - TotalNumber) < MatchScores.Tolerance;3435 /// <summary>36 /// Gets the match percentage.38 /// <value>39 /// The match percentage.40 /// </value>41 public double AverageTotalScore => TotalNumber == 0 ? 0.0 : TotalScore / TotalNumber;41 public double AverageTotalScore => TotalNumber == 0 ? 0.0 : TotalScore / TotalNumber;4243 /// <summary>44 /// Gets the match details.45 /// </summary>46 public IList<KeyValuePair<Type, double>> MatchDetails { get; }46 public IList<KeyValuePair<Type, double>> MatchDetails { get; }4748 /// <summary>49 /// Initializes a new instance of the <see cref="RequestMatchResult"/> class.50 /// </summary>51 public RequestMatchResult() => MatchDetails = new List<KeyValuePair<Type, double>>();51 public RequestMatchResult() => MatchDetails = new List<KeyValuePair<Type, double>>();5253 /// <summary>54 /// Adds the score.57 /// <param name="score">The score.</param>58 /// <returns>The score.</returns>59 public double AddScore(Type matcherType, double score)60 {61 TotalScore += score;62 TotalNumber++;63 MatchDetails.Add(new KeyValuePair<Type, double>(matcherType, score));60 {61 TotalScore += score;62 TotalNumber++;63 MatchDetails.Add(new KeyValuePair<Type, double>(matcherType, score));6465 return score;66 }65 return score;66 }6768 /// <summary>69 /// Compares the current instance with another object of the same type and returns an integer that indicates whe82}4using System.Text;5using System.Net;6using JetBrains.Annotations;7using WireMock.Util;8using WireMock.Validation;910namespace WireMock11{12 /// <summary>13 /// The request.14 /// </summary>15 public class RequestMessage16 {17 /// <summary>18 /// Gets the Client IP Address.19 /// </summary>20 public string ClientIP { get; }2122 /// <summary>23 /// Gets the url.24 /// </summary>25 public string Url { get; }2627 /// <summary>28 /// Gets the DateTime.29 /// </summary>30 public DateTime DateTime { get; set; }3132 /// <summary>33 /// Gets the path.34 /// </summary>35 public string Path { get; }3637 /// <summary>38 /// Gets the method.39 /// </summary>40 public string Method { get; }4142 /// <summary>43 /// Gets the headers.44 /// </summary>45 public IDictionary<string, WireMockList<string>> Headers { get; }4647 /// <summary>48 /// Gets the cookies.49 /// </summary>50 public IDictionary<string, string> Cookies { get; }5152 /// <summary>53 /// Gets the query.54 /// </summary>55 public IDictionary<string, WireMockList<string>> Query { get; }5657 /// <summary>58 /// Gets the raw query.59 /// </summary>60 public string RawQuery { get; }6162 /// <summary>63 /// The body as string.64 /// </summary>65 public string Body { get; }6667 /// <summary>68 /// The body (as JSON object).69 /// </summary>70 public object BodyAsJson { get; set; }7172 /// <summary>73 /// The body (as bytearray).74 /// </summary>75 public byte[] BodyAsBytes { get; set; }7677 /// <summary>78 /// Gets the Host79 /// </summary>80 public string Host { get; }8182 /// <summary>83 /// Gets the protocol84 /// </summary>85 public string Protocol { get; }8687 /// <summary>88 /// Gets the port89 /// </summary>90 public int Port { get; }9192 /// <summary>93 /// Gets the origin94 /// </summary>95 public string Origin { get; }9697 /// <summary>98 /// The body encoding.99 /// </summary>100 public Encoding BodyEncoding { get; }101102 /// <summary>103 /// Initializes a new instance of the <see cref="RequestMessage"/> class.104 /// </summary>105 /// <param name="url">The original url.</param>106 /// <param name="method">The HTTP method.</param>107 /// <param name="clientIP">The client IP Address.</param>108 /// <param name="body">The body.</param>109 /// <param name="headers">The headers.</param>110 /// <param name="cookies">The cookies.</param>111 public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyDat112 {113 Check.NotNull(url, nameof(url));114 Check.NotNull(method, nameof(method));115 Check.NotNull(clientIP, nameof(clientIP));116117 Url = url.ToString();118 Protocol = url.Scheme;119 Host = url.Host;120 Port = url.Port;121 Origin = $"{url.Scheme}://{url.Host}:{url.Port}";122 Path = WebUtility.UrlDecode(url.AbsolutePath);123 Method = method.ToLower();124 ClientIP = clientIP;125126 Body = body?.BodyAsString;127 BodyEncoding = body?.Encoding;128 BodyAsJson = body?.BodyAsJson;129 BodyAsBytes = body?.BodyAsBytes;130131 Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));132 Cookies = cookies;133 RawQuery = WebUtility.UrlDecode(url.Query);134 Query = ParseQuery(RawQuery);135 }136137 /// <summary>138 /// Initializes a new instance of the <see cref="RequestMessage"/> class.139 /// </summary>140 /// <param name="url">The original url.</param>141 /// <param name="method">The HTTP method.</param>142 /// <param name="clientIP">The client IP Address.</param>143 /// <param name="bodyAsBytes">The bodyAsBytes byte[].</param>144 /// <param name="body">The body string.</param>145 /// <param name="bodyEncoding">The body encoding</param>146 /// <param name="headers">The headers.</param>147 /// <param name="cookies">The cookies.</param>148 public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] 149 {150 Check.NotNull(url, nameof(url));151 Check.NotNull(method, nameof(method));152 Check.NotNull(clientIP, nameof(clientIP));153154 Url = url.ToString();155 Protocol = url.Scheme;156 Host = url.Host;157 Port = url.Port;158 Origin = $"{url.Scheme}://{url.Host}:{url.Port}";159 Path = WebUtility.UrlDecode(url.AbsolutePath);160 Method = method.ToLower();161 ClientIP = clientIP;162 BodyAsBytes = bodyAsBytes;163 Body = body;164 BodyEncoding = bodyEncoding;165 Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));166 Cookies = cookies;167 RawQuery = WebUtility.UrlDecode(url.Query);168 Query = ParseQuery(RawQuery);169 }7using WireMock.Models;8using WireMock.Util;9using WireMock.Validation;1011namespace WireMock12{13 /// <summary>14 /// The RequestMessage.15 /// </summary>16 public class RequestMessage17 {18 /// <summary>19 /// Gets the Client IP Address.20 /// </summary>21 public string ClientIP { get; }2223 /// <summary>24 /// Gets the url (relative).25 /// </summary>26 public string Url { get; }2728 /// <summary>29 /// Gets the AbsoluteUrl.30 /// </summary>31 public string AbsoluteUrl { get; }3233 /// <summary>34 /// Gets the DateTime.35 /// </summary>36 public DateTime DateTime { get; set; }3738 /// <summary>39 /// Gets the path (relative).40 /// </summary>41 public string Path { get; }4243 /// <summary>44 /// Gets the AbsolutePath.45 /// </summary>46 public string AbsolutePath { get; }4748 /// <summary>49 /// Gets the path segments.50 /// </summary>51 public string[] PathSegments { get; }5253 /// <summary>54 /// Gets the absolute path segments.55 /// </summary>56 public string[] AbsolutePathSegments { get; }5758 /// <summary>59 /// Gets the method.60 /// </summary>61 public string Method { get; }6263 /// <summary>64 /// Gets the headers.65 /// </summary>66 public IDictionary<string, WireMockList<string>> Headers { get; }6768 /// <summary>69 /// Gets the cookies.70 /// </summary>71 public IDictionary<string, string> Cookies { get; }7273 /// <summary>74 /// Gets the query.75 /// </summary>76 public IDictionary<string, WireMockList<string>> Query { get; }7778 /// <summary>79 /// Gets the raw query.80 /// </summary>81 public string RawQuery { get; }8283 /// <summary>84 /// The original body as string, this is defined when Body or BodyAsJson are not null.85 /// </summary>86 public string Body { get; }8788 /// <summary>89 /// The body (as JSON object).90 /// </summary>91 public object BodyAsJson { get; set; }9293 /// <summary>94 /// The body (as bytearray).95 /// </summary>96 public byte[] BodyAsBytes { get; set; }9798 /// <summary>99 /// Gets the Host100 /// </summary>101 public string Host { get; }102103 /// <summary>104 /// Gets the protocol105 /// </summary>106 public string Protocol { get; }107108 /// <summary>109 /// Gets the port110 /// </summary>111 public int Port { get; }112113 /// <summary>114 /// Gets the origin115 /// </summary>116 public string Origin { get; }117118 /// <summary>119 /// The body encoding.120 /// </summary>121 public Encoding BodyEncoding { get; }122123 /// <summary>124 /// Initializes a new instance of the <see cref="RequestMessage"/> class.125 /// </summary>126 /// <param name="urlDetails">The original url details.</param>127 /// <param name="method">The HTTP method.</param>128 /// <param name="clientIP">The client IP Address.</param>129 /// <param name="body">The body.</param>130 /// <param name="headers">The headers.</param>131 /// <param name="cookies">The cookies.</param>132 public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanB133 {134 Check.NotNull(urlDetails, nameof(urlDetails));135 Check.NotNull(method, nameof(method));136 Check.NotNull(clientIP, nameof(clientIP));137138 AbsoluteUrl = urlDetails.AbsoluteUrl.ToString();139 Url = urlDetails.Url.ToString();140 Protocol = urlDetails.Url.Scheme;141 Host = urlDetails.Url.Host;142 Port = urlDetails.Url.Port;143 Origin = $"{Protocol}://{Host}:{Port}";144145 AbsolutePath = WebUtility.UrlDecode(urlDetails.AbsoluteUrl.AbsolutePath);146 Path = WebUtility.UrlDecode(urlDetails.Url.AbsolutePath);147 PathSegments = Path.Split('/').Skip(1).ToArray();148 AbsolutePathSegments = AbsolutePath.Split('/').Skip(1).ToArray();149150 Method = method.ToLower();151 ClientIP = clientIP;152153 Body = body?.BodyAsString;154 BodyEncoding = body?.Encoding;155 BodyAsJson = body?.BodyAsJson;156 BodyAsBytes = body?.BodyAsBytes;157158 Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));159 Cookies = cookies;160 RawQuery = WebUtility.UrlDecode(urlDetails.Url.Query);161 Query = ParseQuery(RawQuery);162 }163164 private static IDictionary<string, WireMockList<string>> ParseQuery(string queryString)165 {166 if (string.IsNullOrEmpty(queryString))167 {168 return null;169 }170171 private static IDictionary<string, WireMockList<string>> ParseQuery(string queryString)172 {173 if (string.IsNullOrEmpty(queryString))174 {175 return null;176 }177178 if (queryString.StartsWith("?"))179 {180 queryString = queryString.Substring(1);181 }182183 return queryString.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)184 .Aggregate(new Dictionary<string, WireMockList<string>>(),185 (dict, term) =>186 {187 string[] parts = term.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);188 string key = parts[0];189 if (!dict.ContainsKey(key))190 {191 dict.Add(key, new WireMockList<string>());192 }193194 if (parts.Length == 2)195 {196 string[] values = parts[1].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);197 dict[key].AddRange(values);198 }199200 return dict;201 });202 }203204 /// <summary>205 /// Get a query parameter.206 /// </summary>207 /// <param name="key">The key.</param>208 /// <returns>The query parameter.</returns>209 public WireMockList<string> GetParameter(string key)210 {211 if (Query == null)212 {213 return null;214 }215216 return Query.ContainsKey(key) ? Query[key] : null;217 }218 }219}171 if (queryString.StartsWith("?"))172 {173 queryString = queryString.Substring(1);174 }175176 return queryString.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)177 .Aggregate(new Dictionary<string, WireMockList<string>>(),178 (dict, term) =>179 {180 string[] parts = term.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);181 string key = parts[0];182 if (!dict.ContainsKey(key))183 {184 dict.Add(key, new WireMockList<string>());185 }186187 if (parts.Length == 2)188 {189 string[] values = parts[1].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);190 dict[key].AddRange(values);191 }192193 return dict;194 });195 }196197 /// <summary>198 /// Get a query parameter.199 /// </summary>200 /// <param name="key">The key.</param>201 /// <returns>The query parameter.</returns>202 public WireMockList<string> GetParameter(string key)203 {204 if (Query == null)205 {206 return null;207 }208209 return Query.ContainsKey(key) ? Query[key] : null;210 }211 }212}12 /// <summary>13 /// The body function14 /// </summary>15 public Func<string, bool> Func { get; }15 public Func<string, bool> Func { get; }1617 /// <summary>18 /// The body data function for byte[]19 /// </summary>20 public Func<byte[], bool> DataFunc { get; }20 public Func<byte[], bool> DataFunc { get; }2122 /// <summary>23 /// The body data function for json24 /// </summary>25 public Func<object, bool> JsonFunc { get; }25 public Func<object, bool> JsonFunc { get; }2627 /// <summary>28 /// The matcher.29 /// </summary>30 public IMatcher Matcher { get; }30 public IMatcher Matcher { get; }3132 /// <summary>33 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.34 /// </summary>35 /// <param name="body">The body.</param>36 public RequestMessageBodyMatcher([NotNull] string body) : this(new SimMetricsMatcher(body))37 {38 }3940 /// <summary>41 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.42 /// </summary>43 /// <param name="body">The body.</param>44 public RequestMessageBodyMatcher([NotNull] byte[] body) : this(new ExactObjectMatcher(body))45 {46 }4748 /// <summary>49 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.50 /// </summary>51 /// <param name="body">The body.</param>52 public RequestMessageBodyMatcher([NotNull] object body) : this(new ExactObjectMatcher(body))53 {54 }5556 /// <summary>57 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.58 /// </summary>59 /// <param name="func">The function.</param>60 public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)61 {62 Check.NotNull(func, nameof(func));63 Func = func;64 }6566 /// <summary>67 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.68 /// </summary>69 /// <param name="func">The function.</param>70 public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)71 {72 Check.NotNull(func, nameof(func));73 DataFunc = func;74 }7576 /// <summary>77 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.78 /// </summary>79 /// <param name="func">The function.</param>80 public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)81 {82 Check.NotNull(func, nameof(func));83 JsonFunc = func;84 }8586 /// <summary>87 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.88 /// </summary>89 /// <param name="matcher">The matcher.</param>90 public RequestMessageBodyMatcher([NotNull] IMatcher matcher)91 {92 Check.NotNull(matcher, nameof(matcher));93 Matcher = matcher;94 }9596 /// <see cref="IRequestMatcher.GetMatchingScore"/>97 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)98 {99 double score = IsMatch(requestMessage);100 return requestMatchResult.AddScore(GetType(), score);101 }102103 private double IsMatch(RequestMessage requestMessage)104 {105 if (requestMessage.Body != null)106 {107 if (Matcher is IStringMatcher stringMatcher)108 {109 return stringMatcher.IsMatch(requestMessage.Body);110 }111 }112113 if (Matcher is IObjectMatcher objectMatcher)114 {115 if (requestMessage.BodyAsJson != null)116 {117 return objectMatcher.IsMatch(requestMessage.BodyAsJson);118 }119120 if (requestMessage.BodyAsBytes != null)121 {122 return objectMatcher.IsMatch(requestMessage.BodyAsBytes);123 }124 }125126 if (Func != null)127 {128 return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));129 }130131 if (DataFunc != null)132 {133 return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));134 }135136 if (JsonFunc != null)137 {138 return MatchScores.ToScore(requestMessage.BodyAsJson != null && JsonFunc(requestMessage.BodyAsJson));139 }140141 return MatchScores.Mismatch;142 }143 }144}35 /// <param name="matchBehaviour">The match behaviour.</param>36 /// <param name="body">The body.</param>37 public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] string body) : this(new WildcardMatche38 {39 }4041 /// <summary>42 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.43 /// </summary>44 /// <param name="matchBehaviour">The match behaviour.</param>45 /// <param name="body">The body.</param>46 public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] body) : this(new ExactObjectMat47 {48 }4950 /// <summary>51 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.52 /// </summary>53 /// <param name="matchBehaviour">The match behaviour.</param>54 /// <param name="body">The body.</param>55 public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] object body) : this(new ExactObjectMat56 {57 }5859 /// <summary>60 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.61 /// </summary>62 /// <param name="func">The function.</param>63 public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)64 {65 Check.NotNull(func, nameof(func));66 Func = func;67 }6869 /// <summary>70 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.71 /// </summary>72 /// <param name="func">The function.</param>73 public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)74 {75 Check.NotNull(func, nameof(func));76 DataFunc = func;77 }7879 /// <summary>80 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.81 /// </summary>82 /// <param name="func">The function.</param>83 public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)84 {85 Check.NotNull(func, nameof(func));86 JsonFunc = func;87 }8889 /// <summary>90 /// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.91 /// </summary>92 /// <param name="matcher">The matcher.</param>93 public RequestMessageBodyMatcher([NotNull] IMatcher matcher)94 {95 Check.NotNull(matcher, nameof(matcher));96 Matcher = matcher;97 }9899 /// <see cref="IRequestMatcher.GetMatchingScore"/>100 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)101 {102 double score = IsMatch(requestMessage);103 return requestMatchResult.AddScore(GetType(), score);104 }105106 private double IsMatch(RequestMessage requestMessage)107 {108 // Check if the matcher is a IObjectMatcher109 if (Matcher is IObjectMatcher objectMatcher)110 {111 // If the body is a JSON object, try to match.112 if (requestMessage.BodyAsJson != null)113 {114 return objectMatcher.IsMatch(requestMessage.BodyAsJson);115 }116117 // If the body is a byte array, try to match.118 if (requestMessage.BodyAsBytes != null)119 {120 return objectMatcher.IsMatch(requestMessage.BodyAsBytes);121 }122 }123124 // Check if the matcher is a IStringMatcher125 if (Matcher is IStringMatcher stringMatcher)126 {127 // If the body is a JSON object, try to use Body (string) to match.128 if (requestMessage.BodyAsJson != null && requestMessage.Body != null)129 {130 return stringMatcher.IsMatch(requestMessage.Body);131 }132133 // If the string body is defined, try to match.134 if (requestMessage.Body != null)135 {136 return stringMatcher.IsMatch(requestMessage.Body);137 }138 }139140 if (Func != null)141 {142 return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));143 }144145 if (DataFunc != null)146 {147 return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));148 }149150 if (JsonFunc != null)151 {152 return MatchScores.ToScore(requestMessage.BodyAsJson != null && JsonFunc(requestMessage.BodyAsJson));153 }154155 return MatchScores.Mismatch;156 }157 }158}25 /// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.26 /// </summary>27 /// <param name="clientIPs">The clientIPs.</param>28 public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new Wild29 {30 }3132 /// <summary>33 /// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.34 /// </summary>35 /// <param name="matchers">The matchers.</param>36 public RequestMessageClientIPMatcher([NotNull] params IStringMatcher[] matchers)37 {38 Check.NotNull(matchers, nameof(matchers));39 Matchers = matchers;40 }4142 /// <summary>43 /// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.44 /// </summary>45 /// <param name="funcs">The clientIP functions.</param>46 public RequestMessageClientIPMatcher([NotNull] params Func<string, bool>[] funcs)47 {48 Check.NotNull(funcs, nameof(funcs));49 Funcs = funcs;50 }5152 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>53 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)54 {55 double score = IsMatch(requestMessage);56 return requestMatchResult.AddScore(GetType(), score);57 }5859 private double IsMatch(RequestMessage requestMessage)60 {61 if (Matchers != null)62 {63 return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));64 }6566 if (Funcs != null)67 {68 return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.Clie69 }7071 return MatchScores.Mismatch;72 }73 }74}28 /// <param name="matchBehaviour">The match behaviour.</param>29 public RequestMessageClientIPMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] clientIPs) : this(30 {31 }3233 /// <summary>34 /// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.35 /// </summary>36 /// <param name="matchers">The matchers.</param>37 public RequestMessageClientIPMatcher([NotNull] params IStringMatcher[] matchers)38 {39 Check.NotNull(matchers, nameof(matchers));40 Matchers = matchers;41 }4243 /// <summary>44 /// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.45 /// </summary>46 /// <param name="funcs">The clientIP functions.</param>47 public RequestMessageClientIPMatcher([NotNull] params Func<string, bool>[] funcs)48 {49 Check.NotNull(funcs, nameof(funcs));50 Funcs = funcs;51 }5253 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>54 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)55 {56 double score = IsMatch(requestMessage);57 return requestMatchResult.AddScore(GetType(), score);58 }5960 private double IsMatch(RequestMessage requestMessage)61 {62 if (Matchers != null)63 {64 return Matchers.Max(matcher => matcher.IsMatch(requestMessage.ClientIP));65 }6667 if (Funcs != null)68 {69 return MatchScores.ToScore(requestMessage.ClientIP != null && Funcs.Any(func => func(requestMessage.Clie70 }7172 return MatchScores.Mismatch;73 }74 }75}18 /// <value>19 /// The request matchers.20 /// </value>21 private IEnumerable<IRequestMatcher> RequestMatchers { get; }21 private IEnumerable<IRequestMatcher> RequestMatchers { get; }2223 /// <summary>24 /// Initializes a new instance of the <see cref="RequestMessageCompositeMatcher"/> class.25 /// </summary>26 /// <param name="requestMatchers">The request matchers.</param>27 /// <param name="type">The CompositeMatcherType type (Defaults to 'And')</param>28 protected RequestMessageCompositeMatcher([NotNull] IEnumerable<IRequestMatcher> requestMatchers, CompositeMatche29 {30 Check.NotNull(requestMatchers, nameof(requestMatchers));28 protected RequestMessageCompositeMatcher([NotNull] IEnumerable<IRequestMatcher> requestMatchers, CompositeMatche29 {30 Check.NotNull(requestMatchers, nameof(requestMatchers));3132 _type = type;33 RequestMatchers = requestMatchers;34 }32 _type = type;33 RequestMatchers = requestMatchers;34 }3536 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>37 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)38 {39 if (!RequestMatchers.Any())40 {41 return MatchScores.Mismatch;38 {39 if (!RequestMatchers.Any())40 {41 return MatchScores.Mismatch;42 }4344 if (_type == CompositeMatcherType.And)45 {46 return RequestMatchers.Average(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, request44 if (_type == CompositeMatcherType.And)45 {46 return RequestMatchers.Average(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, request47 }4849 return RequestMatchers.Max(requestMatcher => requestMatcher.GetMatchingScore(requestMessage, requestMatchRes50 }50 }51 }52}11 /// </summary>12 public class RequestMessageCookieMatcher : IRequestMatcher13 {14 /// <value>15 /// The funcs.16 /// </value>17 public Func<IDictionary<string, string>, bool>[] Funcs { get; }1819 /// <summary>20 /// The name21 /// </summary>22 public string Name { get; }2324 /// <value>25 /// The matchers.26 /// </value>27 public IStringMatcher[] Matchers { get; }2829 /// <summary>30 /// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.31 /// </summary>32 /// <param name="name">The name.</param>33 /// <param name="pattern">The pattern.</param>34 /// <param name="ignoreCase">The ignoreCase.</param>35 public RequestMessageCookieMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)36 {37 Check.NotNull(name, nameof(name));38 Check.NotNull(pattern, nameof(pattern));3940 Name = name;41 Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };42 }14 private readonly MatchBehaviour _matchBehaviour;15 private readonly bool _ignoreCase;1617 /// <value>18 /// The funcs.19 /// </value>20 public Func<IDictionary<string, string>, bool>[] Funcs { get; }2122 /// <summary>23 /// The name24 /// </summary>25 public string Name { get; }2627 /// <value>28 /// The matchers.29 /// </value>30 public IStringMatcher[] Matchers { get; }3132 /// <summary>33 /// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.34 /// </summary>35 /// <param name="matchBehaviour">The match behaviour.</param>36 /// <param name="name">The name.</param>37 /// <param name="pattern">The pattern.</param>38 /// <param name="ignoreCase">The ignoreCase.</param>39 public RequestMessageCookieMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string patter40 {41 Check.NotNull(name, nameof(name));42 Check.NotNull(pattern, nameof(pattern));4344 /// <summary>45 /// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.46 /// </summary>47 /// <param name="name">The name.</param>48 /// <param name="matchers">The matchers.</param>49 public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)50 {51 Check.NotNull(name, nameof(name));52 Check.NotNull(matchers, nameof(matchers));5354 Name = name;55 Matchers = matchers;56 }5758 /// <summary>59 /// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.60 /// </summary>61 /// <param name="funcs">The funcs.</param>62 public RequestMessageCookieMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)63 {64 Check.NotNull(funcs, nameof(funcs));6566 Funcs = funcs;67 }6869 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>70 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)71 {72 double score = IsMatch(requestMessage);73 return requestMatchResult.AddScore(GetType(), score);74 }7576 private double IsMatch(RequestMessage requestMessage)77 {78 if (requestMessage.Cookies == null)79 {80 return MatchScores.Mismatch;81 }8283 if (Funcs != null)84 {85 return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Cookies)));86 }8788 if (Matchers == null)89 {90 return MatchScores.Mismatch;91 }9293 if (!requestMessage.Cookies.ContainsKey(Name))94 {95 return MatchScores.Mismatch;96 }9798 string value = requestMessage.Cookies[Name];99 return Matchers.Max(m => m.IsMatch(value));100 }101 }102}44 _matchBehaviour = matchBehaviour;45 _ignoreCase = ignoreCase;46 Name = name;47 Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };48 }4950 /// <summary>51 /// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.52 /// </summary>53 /// <param name="name">The name.</param>54 /// <param name="matchers">The matchers.</param>55 public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)56 {57 Check.NotNull(name, nameof(name));58 Check.NotNull(matchers, nameof(matchers));5960 Name = name;61 Matchers = matchers;62 }6364 /// <summary>65 /// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.66 /// </summary>67 /// <param name="funcs">The funcs.</param>68 public RequestMessageCookieMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)69 {70 Check.NotNull(funcs, nameof(funcs));7172 Funcs = funcs;73 }7475 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>76 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)77 {78 double score = IsMatch(requestMessage);79 return requestMatchResult.AddScore(GetType(), score);80 }8182 private double IsMatch(RequestMessage requestMessage)83 {84 if (requestMessage.Cookies == null)85 {86 return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);87 }8889 // Check if we want to use IgnoreCase to compare the Cookie-Name and Cookie-Value90 var cookies = !_ignoreCase ? requestMessage.Cookies : new Dictionary<string, string>(requestMessage.Cookies,9192 if (Funcs != null)93 {94 return MatchScores.ToScore(Funcs.Any(f => f(cookies)));95 }9697 if (Matchers == null)98 {99 return MatchScores.Mismatch;100 }101102 if (!cookies.ContainsKey(Name))103 {104 return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);105 }106107 string value = cookies[Name];108 return Matchers.Max(m => m.IsMatch(value));109 }110 }111}13 /// <inheritdoc cref="IRequestMatcher"/>14 public class RequestMessageHeaderMatcher : IRequestMatcher15 {16 /// <summary>17 /// The functions18 /// </summary>19 public Func<IDictionary<string, string[]>, bool>[] Funcs { get; }2021 /// <summary>22 /// The name23 /// </summary>24 public string Name { get; }2526 /// <value>27 /// The matchers.28 /// </value>29 public IStringMatcher[] Matchers { get; }3031 /// <summary>32 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.33 /// </summary>34 /// <param name="name">The name.</param>35 /// <param name="pattern">The pattern.</param>36 /// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>37 public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)38 {39 Check.NotNull(name, nameof(name));40 Check.NotNull(pattern, nameof(pattern));4142 Name = name;43 Matchers = new IStringMatcher[] { new WildcardMatcher(pattern, ignoreCase) };44 }16 private readonly MatchBehaviour _matchBehaviour;17 private readonly bool _ignoreCase;1819 /// <summary>20 /// The functions21 /// </summary>22 public Func<IDictionary<string, string[]>, bool>[] Funcs { get; }2324 /// <summary>25 /// The name26 /// </summary>27 public string Name { get; }2829 /// <value>30 /// The matchers.31 /// </value>32 public IStringMatcher[] Matchers { get; }3334 /// <summary>35 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.36 /// </summary>37 /// <param name="name">The name.</param>38 /// <param name="pattern">The pattern.</param>39 /// <param name="ignoreCase">Ignore the case from the pattern.</param>40 /// <param name="matchBehaviour">The match behaviour.</param>41 public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string patter42 {43 Check.NotNull(name, nameof(name));44 Check.NotNull(pattern, nameof(pattern));4546 /// <summary>47 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.48 /// </summary>49 /// <param name="name">The name.</param>50 /// <param name="patterns">The patterns.</param>51 /// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>52 public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string[] patterns, bool ignoreCase = true)53 {54 Check.NotNull(name, nameof(name));55 Check.NotNull(patterns, nameof(patterns));5657 Name = name;58 Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IStringMatcher>().ToArr59 }6061 /// <summary>62 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.63 /// </summary>64 /// <param name="name">The name.</param>65 /// <param name="matchers">The matchers.</param>66 public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)67 {68 Check.NotNull(name, nameof(name));69 Check.NotNull(matchers, nameof(matchers));7071 Name = name;72 Matchers = matchers;73 }7475 /// <summary>76 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.77 /// </summary>78 /// <param name="funcs">The funcs.</param>79 public RequestMessageHeaderMatcher([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs)80 {81 Check.NotNull(funcs, nameof(funcs));8283 Funcs = funcs;84 }8586 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>87 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)88 {89 double score = IsMatch(requestMessage);90 return requestMatchResult.AddScore(GetType(), score);91 }9293 private double IsMatch(RequestMessage requestMessage)94 {95 if (requestMessage.Headers == null)96 {97 return MatchScores.Mismatch;98 }99100 if (Funcs != null)101 {102 return MatchScores.ToScore(Funcs.Any(f => f(requestMessage.Headers.ToDictionary(entry => entry.Key, entr103 }104105 if (Matchers == null)106 {107 return MatchScores.Mismatch;108 }109110 if (!requestMessage.Headers.ContainsKey(Name))111 {112 return MatchScores.Mismatch;113 }114115 WireMockList<string> list = requestMessage.Headers[Name];116 return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?117 }118 }119}46 _matchBehaviour = matchBehaviour;47 _ignoreCase = ignoreCase;48 Name = name;49 Matchers = new IStringMatcher[] { new WildcardMatcher(matchBehaviour, pattern, ignoreCase) };50 }5152 /// <summary>53 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.54 /// </summary>55 /// <param name="name">The name.</param>56 /// <param name="patterns">The patterns.</param>57 /// <param name="ignoreCase">Ignore the case from the pattern.</param>58 /// <param name="matchBehaviour">The match behaviour.</param>59 public RequestMessageHeaderMatcher(MatchBehaviour matchBehaviour, [NotNull] string name, [NotNull] string[] patt60 {61 Check.NotNull(name, nameof(name));62 Check.NotNull(patterns, nameof(patterns));6364 _matchBehaviour = matchBehaviour;65 _ignoreCase = ignoreCase;66 Name = name;67 Matchers = patterns.Select(pattern => new WildcardMatcher(matchBehaviour, pattern, ignoreCase)).Cast<IString68 }6970 /// <summary>71 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.72 /// </summary>73 /// <param name="name">The name.</param>74 /// <param name="matchers">The matchers.</param>75 public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IStringMatcher[] matchers)76 {77 Check.NotNull(name, nameof(name));78 Check.NotNull(matchers, nameof(matchers));7980 Name = name;81 Matchers = matchers;82 }8384 /// <summary>85 /// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.86 /// </summary>87 /// <param name="funcs">The funcs.</param>88 public RequestMessageHeaderMatcher([NotNull] params Func<IDictionary<string, string[]>, bool>[] funcs)89 {90 Check.NotNull(funcs, nameof(funcs));9192 Funcs = funcs;93 }9495 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>96 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)97 {98 double score = IsMatch(requestMessage);99 return requestMatchResult.AddScore(GetType(), score);100 }101102 private double IsMatch(RequestMessage requestMessage)103 {104 if (requestMessage.Headers == null)105 {106 return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);107 }108109 // Check if we want to use IgnoreCase to compare the Header-Name and Header-Value(s)110 var headers = !_ignoreCase ? requestMessage.Headers : new Dictionary<string, WireMockList<string>>(requestMe111112 if (Funcs != null)113 {114 return MatchScores.ToScore(Funcs.Any(f => f(headers.ToDictionary(entry => entry.Key, entry => entry.Valu115 }116117 if (Matchers == null)118 {119 return MatchScores.Mismatch;120 }121122 if (!headers.ContainsKey(Name))123 {124 return MatchBehaviourHelper.Convert(_matchBehaviour, MatchScores.Mismatch);125 }126127 WireMockList<string> list = headers[Name];128 return Matchers.Max(m => list.Max(value => m.IsMatch(value))); // TODO : is this correct ?129 }130 }131}9 /// </summary>10 internal class RequestMessageMethodMatcher : IRequestMatcher11 {12 /// <summary>13 /// The methods14 /// </summary>15 public string[] Methods { get; }1617 /// <summary>18 /// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class.19 /// </summary>20 /// <param name="methods">21 /// The verb.22 /// </param>23 public RequestMessageMethodMatcher([NotNull] params string[] methods)24 {25 Check.NotNull(methods, nameof(methods));26 Methods = methods.Select(v => v.ToLower()).ToArray();27 }12 private readonly MatchBehaviour _matchBehaviour;1314 /// <summary>15 /// The methods16 /// </summary>17 public string[] Methods { get; }1819 /// <summary>20 /// Initializes a new instance of the <see cref="RequestMessageMethodMatcher"/> class.21 /// </summary>22 /// <param name="matchBehaviour">The match behaviour.</param>23 /// <param name="methods">The methods.</param>24 public RequestMessageMethodMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] methods)25 {26 Check.NotNull(methods, nameof(methods));27 _matchBehaviour = matchBehaviour;2829 /// <summary>30 /// Determines whether the specified RequestMessage is match.31 /// </summary>32 /// <param name="requestMessage">The RequestMessage.</param>33 /// <param name="requestMatchResult">The RequestMatchResult.</param>34 /// <returns>35 /// A value between 0.0 - 1.0 of the similarity.36 /// </returns>37 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)38 {39 double score = IsMatch(requestMessage);40 return requestMatchResult.AddScore(GetType(), score);41 }4243 private double IsMatch(RequestMessage requestMessage)44 {45 return MatchScores.ToScore(Methods.Contains(requestMessage.Method));46 }47 }48}29 Methods = methods.Select(v => v.ToLower()).ToArray();30 }3132 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>33 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)34 {35 double score = MatchBehaviourHelper.Convert(_matchBehaviour, IsMatch(requestMessage));36 return requestMatchResult.AddScore(GetType(), score);37 }3839 private double IsMatch(RequestMessage requestMessage)40 {41 return MatchScores.ToScore(Methods.Contains(requestMessage.Method));42 }43 }44}| Class: | WireMock.Matchers.Request.RequestMessageParamMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\Request\RequestMessageParamMatcher.cs |
| Covered lines: | 46 |
| Uncovered lines: | 1 |
| Coverable lines: | 47 |
| Total lines: | 120 |
| Line coverage: | 97.8% |
| Branch coverage: | 85% |
12 public class RequestMessagePathMatcher : IRequestMatcher13 {14 /// <summary>15 /// The matcher.15 /// The matchers16 /// </summary>17 public IReadOnlyList<IStringMatcher> Matchers { get; }17 public IReadOnlyList<IStringMatcher> Matchers { get; }1819 /// <summary>20 /// The path functions24 /// <summary>25 /// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.26 /// </summary>27 /// <param name="paths">The paths.</param>28 public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatche29 {30 }3132 /// <summary>33 /// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.34 /// </summary>35 /// <param name="matchers">The matchers.</param>36 public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)37 {38 Check.NotNull(matchers, nameof(matchers));39 Matchers = matchers;40 }4142 /// <summary>43 /// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.44 /// </summary>45 /// <param name="funcs">The path functions.</param>46 public RequestMessagePathMatcher([NotNull] params Func<string, bool>[] funcs)47 {48 Check.NotNull(funcs, nameof(funcs));49 Funcs = funcs;50 }27 /// <param name="matchBehaviour">The match behaviour.</param>28 /// <param name="paths">The paths.</param>29 public RequestMessagePathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] paths) : this(paths.Se30 {31 }3233 /// <summary>34 /// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.35 /// </summary>36 /// <param name="matchers">The matchers.</param>37 public RequestMessagePathMatcher([NotNull] params IStringMatcher[] matchers)38 {39 Check.NotNull(matchers, nameof(matchers));4041 Matchers = matchers;42 }4344 /// <summary>45 /// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.46 /// </summary>47 /// <param name="funcs">The path functions.</param>48 public RequestMessagePathMatcher([NotNull] params Func<string, bool>[] funcs)49 {50 Check.NotNull(funcs, nameof(funcs));5152 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>53 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)54 {55 double score = IsMatch(requestMessage);56 return requestMatchResult.AddScore(GetType(), score);57 }5859 private double IsMatch(RequestMessage requestMessage)60 {61 if (Matchers != null)62 {63 return Matchers.Max(m => m.IsMatch(requestMessage.Path));64 }6566 if (Funcs != null)67 {68 return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));69 }7071 return MatchScores.Mismatch;72 }73 }74}52 Funcs = funcs;53 }5455 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>56 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)57 {58 double score = IsMatch(requestMessage);59 return requestMatchResult.AddScore(GetType(), score);60 }6162 private double IsMatch(RequestMessage requestMessage)63 {64 if (Matchers != null)65 {66 return Matchers.Max(m => m.IsMatch(requestMessage.Path));67 }6869 if (Funcs != null)70 {71 return MatchScores.ToScore(requestMessage.Path != null && Funcs.Any(func => func(requestMessage.Path)));72 }7374 return MatchScores.Mismatch;75 }76 }77}7 /// </summary>8 internal class RequestMessageScenarioAndStateMatcher : IRequestMatcher9 {10 ///// <summary>11 ///// Scenario.12 ///// </summary>13 //[CanBeNull] private string _scenario;1415 /// <summary>16 /// Execution state condition for the current mapping.17 /// </summary>18 [CanBeNull]19 private readonly object _executionConditionState;2021 /// <summary>22 /// The next state which will be signaled after the current mapping execution.23 /// In case the value is null state will not be changed.24 /// </summary>25 [CanBeNull]26 private readonly object _nextState;2728 /// <summary>29 /// Initializes a new instance of the <see cref="RequestMessageScenarioAndStateMatcher"/> class.30 /// </summary>31 /// <param name="nextState">The next state.</param>32 /// <param name="executionConditionState">Execution state condition for the current mapping.</param>33 public RequestMessageScenarioAndStateMatcher([CanBeNull] object nextState, [CanBeNull] object executionCondition34 {35 _nextState = nextState;36 _executionConditionState = executionConditionState;37 }3839 /// <inheritdoc />40 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)41 {42 double score = IsMatch();43 return requestMatchResult.AddScore(GetType(), score);44 }4546 private double IsMatch()47 {48 return Equals(_executionConditionState, _nextState) ? MatchScores.Perfect : MatchScores.Mismatch;49 }50 }51}10 /// <summary>11 /// Execution state condition for the current mapping.12 /// </summary>13 [CanBeNull]14 private readonly string _executionConditionState;1516 /// <summary>17 /// The next state which will be signaled after the current mapping execution.18 /// In case the value is null state will not be changed.19 /// </summary>20 [CanBeNull]21 private readonly string _nextState;2223 /// <summary>24 /// Initializes a new instance of the <see cref="RequestMessageScenarioAndStateMatcher"/> class.25 /// </summary>26 /// <param name="nextState">The next state.</param>27 /// <param name="executionConditionState">Execution state condition for the current mapping.</param>28 public RequestMessageScenarioAndStateMatcher([CanBeNull] string nextState, [CanBeNull] string executionCondition29 {30 _nextState = nextState;31 _executionConditionState = executionConditionState;32 }3334 /// <inheritdoc />35 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)36 {37 double score = IsMatch();38 return requestMatchResult.AddScore(GetType(), score);39 }4041 private double IsMatch()42 {43 return Equals(_executionConditionState, _nextState) ? MatchScores.Perfect : MatchScores.Mismatch;44 }45 }46}24 /// <summary>25 /// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.26 /// </summary>27 /// <param name="urls">The urls.</param>28 public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(ur29 {30 }3132 /// <summary>33 /// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.34 /// </summary>35 /// <param name="matchers">The matchers.</param>36 public RequestMessageUrlMatcher([NotNull] params IStringMatcher[] matchers)37 {38 Check.NotNull(matchers, nameof(matchers));39 Matchers = matchers;40 }4142 /// <summary>43 /// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.44 /// </summary>45 /// <param name="funcs">The url functions.</param>46 public RequestMessageUrlMatcher([NotNull] params Func<string, bool>[] funcs)47 {48 Check.NotNull(funcs, nameof(funcs));49 Funcs = funcs;50 }5152 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>53 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)54 {55 double score = IsMatch(requestMessage);56 return requestMatchResult.AddScore(GetType(), score);57 }5859 private double IsMatch(RequestMessage requestMessage)60 {61 if (Matchers != null)62 {63 return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));64 }6566 if (Funcs != null)67 {68 return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));69 }7071 return MatchScores.Mismatch;72 }73 }74}27 /// <param name="matchBehaviour">The match behaviour.</param>28 /// <param name="urls">The urls.</param>29 public RequestMessageUrlMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] urls) : this(urls.Selec30 {31 }3233 /// <summary>34 /// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.35 /// </summary>36 /// <param name="matchers">The matchers.</param>37 public RequestMessageUrlMatcher([NotNull] params IStringMatcher[] matchers)38 {39 Check.NotNull(matchers, nameof(matchers));40 Matchers = matchers;41 }4243 /// <summary>44 /// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.45 /// </summary>46 /// <param name="funcs">The url functions.</param>47 public RequestMessageUrlMatcher([NotNull] params Func<string, bool>[] funcs)48 {49 Check.NotNull(funcs, nameof(funcs));50 Funcs = funcs;51 }5253 /// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>54 public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)55 {56 double score = IsMatch(requestMessage);57 return requestMatchResult.AddScore(GetType(), score);58 }5960 private double IsMatch(RequestMessage requestMessage)61 {62 if (Matchers != null)63 {64 return Matchers.Max(matcher => matcher.IsMatch(requestMessage.Url));65 }6667 if (Funcs != null)68 {69 return MatchScores.ToScore(requestMessage.Url != null && Funcs.Any(func => func(requestMessage.Url)));70 }7172 return MatchScores.Mismatch;73 }74 }75}10 /// <summary>11 /// Gets or sets the ClientIP. (Can be a string or a ClientIPModel)12 /// </summary>13 /// <value>14 /// The ClientIP.15 /// </value>16 public object ClientIP { get; set; }1718 /// <summary>19 /// Gets or sets the Path. (Can be a string or a PathModel)20 /// </summary>21 /// <value>22 /// The Path.23 /// </value>24 public object Path { get; set; }2526 /// <summary>27 /// Gets or sets the Url. (Can be a string or a UrlModel)28 /// </summary>29 /// <value>30 /// The URL.31 /// </value>32 public object Url { get; set; }3334 /// <summary>35 /// The methods36 /// </summary>37 public string[] Methods { get; set; }3839 /// <summary>40 /// Gets or sets the Headers.41 /// </summary>42 /// <value>43 /// The Headers.44 /// </value>45 public IList<HeaderModel> Headers { get; set; }4647 /// <summary>48 /// Gets or sets the Cookies.49 /// </summary>50 /// <value>51 /// The Cookies.52 /// </value>53 public IList<CookieModel> Cookies { get; set; }5455 /// <summary>56 /// Gets or sets the Params.57 /// </summary>58 /// <value>59 /// The Headers.60 /// </value>61 public IList<ParamModel> Params { get; set; }6263 /// <summary>64 /// Gets or sets the body.65 /// </summary>66 /// <value>67 /// The body.68 /// </value>69 public BodyModel Body { get; set; }70 }71}13 public object ClientIP { get; set; }1415 /// <summary>16 /// Gets or sets the Path. (Can be a string or a PathModel)17 /// </summary>18 public object Path { get; set; }1920 /// <summary>21 /// Gets or sets the Url. (Can be a string or a UrlModel)22 /// </summary>23 public object Url { get; set; }2425 /// <summary>26 /// The methods27 /// </summary>28 public string[] Methods { get; set; }2930 /// <summary>31 /// Gets or sets the Headers.32 /// </summary>33 public IList<HeaderModel> Headers { get; set; }3435 /// <summary>36 /// Gets or sets the Cookies.37 /// </summary>38 public IList<CookieModel> Cookies { get; set; }3940 /// <summary>41 /// Gets or sets the Params.42 /// </summary>43 public IList<ParamModel> Params { get; set; }4445 /// <summary>46 /// Gets or sets the body.47 /// </summary>48 public BodyModel Body { get; set; }49 }50}10 internal class RespondWithAProvider : IRespondWithAProvider11 {12 private int _priority;13 private Guid? _guid;14 private string _title;15 private string _path;16 private object _executionConditionState;17 private object _nextState;18 private string _scenario;19 private readonly RegistrationCallback _registrationCallback;20 private readonly IRequestMatcher _requestMatcher;2122 /// <summary>23 /// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.24 /// </summary>25 /// <param name="registrationCallback">The registration callback.</param>26 /// <param name="requestMatcher">The request matcher.</param>27 public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher)28 {29 _registrationCallback = registrationCallback;30 _requestMatcher = requestMatcher;31 }3233 /// <summary>34 /// The respond with.35 /// </summary>36 /// <param name="provider">The provider.</param>37 public void RespondWith(IResponseProvider provider)38 {39 var mappingGuid = _guid ?? Guid.NewGuid();40 _registrationCallback(new Mapping(mappingGuid, _title, _path, _requestMatcher, provider, _priority, _scenari41 }13 private string _title;14 private string _path;15 private string _executionConditionState;16 private string _nextState;17 private string _scenario;18 private readonly RegistrationCallback _registrationCallback;19 private readonly IRequestMatcher _requestMatcher;2021 public Guid Guid { get; private set; } = Guid.NewGuid();2223 /// <summary>24 /// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.25 /// </summary>26 /// <param name="registrationCallback">The registration callback.</param>27 /// <param name="requestMatcher">The request matcher.</param>28 public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher)29 {30 _registrationCallback = registrationCallback;31 _requestMatcher = requestMatcher;32 }3334 /// <summary>35 /// The respond with.36 /// </summary>37 /// <param name="provider">The provider.</param>38 public void RespondWith(IResponseProvider provider)39 {40 _registrationCallback(new Mapping(Guid, _title, _path, _requestMatcher, provider, _priority, _scenario, _exe41 }4243 /// <see cref="IRespondWithAProvider.WithGuid(string)"/>44 public IRespondWithAProvider WithGuid(string guid)45 {46 return WithGuid(Guid.Parse(guid));47 }45 {46 return WithGuid(Guid.Parse(guid));47 }4849 /// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>50 public IRespondWithAProvider WithGuid(Guid guid)51 {52 _guid = guid;51 {52 Guid = guid;5354 return this;55 }54 return this;55 }5657 /// <see cref="IRespondWithAProvider.WithTitle"/>58 public IRespondWithAProvider WithTitle(string title)59 {60 _title = title;59 {60 _title = title;6162 return this;63 }62 return this;63 }6465 /// <see cref="IRespondWithAProvider.WithPath"/>66 public IRespondWithAProvider WithPath(string path)67 {68 _path = path;67 {68 _path = path;6970 return this;71 }70 return this;71 }7273 /// <see cref="IRespondWithAProvider.AtPriority"/>74 public IRespondWithAProvider AtPriority(int priority)75 {76 _priority = priority;75 {76 _priority = priority;7778 return this;79 }78 return this;79 }8081 /// <see cref="IRespondWithAProvider.InScenario(string)"/>82 public IRespondWithAProvider InScenario(string scenario)83 {84 _scenario = scenario;83 {84 _scenario = scenario;8586 return this;87 }86 return this;87 }8889 /// <see cref="IRespondWithAProvider.WhenStateIs"/>90 public IRespondWithAProvider WhenStateIs(object state)91 {92 if (string.IsNullOrEmpty(_scenario))90 public IRespondWithAProvider WhenStateIs(string state)91 {92 if (string.IsNullOrEmpty(_scenario))93 {94 throw new NotSupportedException("Unable to set state condition when no scenario is defined.");95 }9697 //if (_nextState != null)98 //{99 // throw new NotSupportedException("Unable to set state condition when next state is defined.");100 //}97 _executionConditionState = state;9899 return this;100 }101102 _executionConditionState = state;103104 return this;105 }106107 /// <see cref="IRespondWithAProvider.WillSetStateTo"/>108 public IRespondWithAProvider WillSetStateTo(object state)109 {110 if (string.IsNullOrEmpty(_scenario))111 {112 throw new NotSupportedException("Unable to set next state when no scenario is defined.");113 }114115 _nextState = state;116117 return this;118 }119 }120}102 /// <see cref="IRespondWithAProvider.WillSetStateTo"/>103 public IRespondWithAProvider WillSetStateTo(string state)104 {105 if (string.IsNullOrEmpty(_scenario))106 {107 throw new NotSupportedException("Unable to set next state when no scenario is defined.");108 }109110 _nextState = state;111112 return this;113 }114 }115}26 /// <summary>27 /// The delay28 /// </summary>29 public TimeSpan? Delay { get; private set; }29 public TimeSpan? Delay { get; private set; }3031 /// <summary>32 /// Gets a value indicating whether [use transformer].33 /// </summary>34 /// <value>35 /// <c>true</c> if [use transformer]; otherwise, <c>false</c>.36 /// </value>37 public bool UseTransformer { get; private set; }3839 /// <summary>40 /// The Proxy URL to use.41 /// </summary>42 public string ProxyUrl { get; private set; }4344 /// <summary>45 /// The client X509Certificate2 Thumbprint or SubjectName to use.46 /// </summary>47 public string ClientX509Certificate2ThumbprintOrSubjectName { get; private set; }4849 /// <summary>50 /// Gets the response message.51 /// </summary>52 public ResponseMessage ResponseMessage { get; }5354 /// <summary>55 /// A delegate to execute to generate the response56 /// </summary>57 public Func<RequestMessage, ResponseMessage> Callback { get; private set; }5859 /// <summary>60 /// Creates this instance.61 /// </summary>62 /// <param name="responseMessage">ResponseMessage</param>63 /// <returns>A <see cref="IResponseBuilder"/>.</returns>64 [PublicAPI]65 public static IResponseBuilder Create([CanBeNull] ResponseMessage responseMessage = null)66 {67 var message = responseMessage ?? new ResponseMessage { StatusCode = (int)HttpStatusCode.OK };68 return new Response(message);69 }7071 /// <summary>72 /// Creates this instance with the specified function.73 /// </summary>74 /// <param name="func">The callback function.</param>75 /// <returns>A <see cref="IResponseBuilder"/>.</returns>76 [PublicAPI]77 public static IResponseBuilder Create([NotNull] Func<ResponseMessage> func)78 {79 Check.NotNull(func, nameof(func));34 public bool UseTransformer { get; private set; }3536 /// <summary>37 /// The Proxy URL to use.38 /// </summary>39 public string ProxyUrl { get; private set; }4041 /// <summary>42 /// The client X509Certificate2 Thumbprint or SubjectName to use.43 /// </summary>44 public string ClientX509Certificate2ThumbprintOrSubjectName { get; private set; }4546 /// <summary>47 /// Gets the response message.48 /// </summary>49 public ResponseMessage ResponseMessage { get; }5051 /// <summary>52 /// A delegate to execute to generate the response53 /// </summary>54 public Func<RequestMessage, ResponseMessage> Callback { get; private set; }5556 /// <summary>57 /// Creates this instance.58 /// </summary>59 /// <param name="responseMessage">ResponseMessage</param>60 /// <returns>A <see cref="IResponseBuilder"/>.</returns>61 [PublicAPI]62 public static IResponseBuilder Create([CanBeNull] ResponseMessage responseMessage = null)63 {64 var message = responseMessage ?? new ResponseMessage { StatusCode = (int)HttpStatusCode.OK };65 return new Response(message);66 }6768 /// <summary>69 /// Creates this instance with the specified function.70 /// </summary>71 /// <param name="func">The callback function.</param>72 /// <returns>A <see cref="IResponseBuilder"/>.</returns>73 [PublicAPI]74 public static IResponseBuilder Create([NotNull] Func<ResponseMessage> func)75 {76 Check.NotNull(func, nameof(func));7778 return new Response(func());79 }8081 return new Response(func());82 }8384 /// <summary>85 /// Initializes a new instance of the <see cref="Response"/> class.86 /// </summary>87 /// <param name="responseMessage">88 /// The response.89 /// </param>90 private Response(ResponseMessage responseMessage)91 {92 ResponseMessage = responseMessage;93 }9495 /// <summary>96 /// The with status code.97 /// </summary>98 /// <param name="code">The code.</param>99 /// <returns>A <see cref="IResponseBuilder"/>.</returns>\100 [PublicAPI]101 public IResponseBuilder WithStatusCode(int code)102 {103 ResponseMessage.StatusCode = code;104 return this;105 }106107 /// <summary>108 /// The with status code.109 /// </summary>110 /// <param name="code">The code.</param>111 /// <returns>A <see cref="IResponseBuilder"/>.</returns>112 [PublicAPI]113 public IResponseBuilder WithStatusCode(HttpStatusCode code)114 {115 return WithStatusCode((int)code);116 }117118 /// <summary>119 /// The with Success status code (200).120 /// </summary>121 /// <returns>A <see cref="IResponseBuilder"/>.</returns>122 [PublicAPI]123 public IResponseBuilder WithSuccess()124 {125 return WithStatusCode((int)HttpStatusCode.OK);126 }127128 /// <summary>129 /// The with NotFound status code (404).130 /// </summary>131 /// <returns>The <see cref="IResponseBuilder"/>.</returns>132 [PublicAPI]133 public IResponseBuilder WithNotFound()134 {135 return WithStatusCode((int)HttpStatusCode.NotFound);136 }137138 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeader(string, string[])"/>139 public IResponseBuilder WithHeader(string name, params string[] values)140 {141 Check.NotNull(name, nameof(name));142143 ResponseMessage.AddHeader(name, values);144 return this;145 }146147 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, string})"/>148 public IResponseBuilder WithHeaders(IDictionary<string, string> headers)149 {150 Check.NotNull(headers, nameof(headers));151152 ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList<string>(head153 return this;154 }155156 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, string[]})"/>157 public IResponseBuilder WithHeaders(IDictionary<string, string[]> headers)158 {159 Check.NotNull(headers, nameof(headers));160161 ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList<string>(head162 return this;163 }164165 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, WireMockList{string}})"/>166 public IResponseBuilder WithHeaders(IDictionary<string, WireMockList<string>> headers)167 {168 ResponseMessage.Headers = headers;169 return this;170 }171172 /// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, string}, string, Encoding)"/>173 public IResponseBuilder WithBody(Func<RequestMessage, string> bodyFactory, string destination = BodyDestinationF174 {175 return WithCallback(req => new ResponseMessage { Body = bodyFactory(req) });176 }177178 /// <inheritdoc cref="IBodyResponseBuilder.WithBody(byte[], string, Encoding)"/>179 public IResponseBuilder WithBody(byte[] body, string destination, Encoding encoding = null)180 {181 Check.NotNull(body, nameof(body));182183 ResponseMessage.BodyDestination = destination;184185 switch (destination)186 {187 case BodyDestinationFormat.String:188 var enc = encoding ?? Encoding.UTF8;189 ResponseMessage.BodyAsBytes = null;190 ResponseMessage.Body = enc.GetString(body);191 ResponseMessage.BodyEncoding = enc;192 break;193194 default:195 ResponseMessage.BodyAsBytes = body;196 ResponseMessage.BodyEncoding = null;197 break;198 }199200 return this;201 }202203 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromFile"/>204 public IResponseBuilder WithBodyFromFile(string filename, bool cache = true)205 {206 Check.NotNull(filename, nameof(filename));207208 ResponseMessage.BodyEncoding = null;209 ResponseMessage.BodyAsFileIsCached = cache;210211 if (cache)212 {213 ResponseMessage.Body = null;214 ResponseMessage.BodyAsBytes = File.ReadAllBytes(filename);215 ResponseMessage.BodyAsFile = null;216 }217 else218 {219 ResponseMessage.Body = null;220 ResponseMessage.BodyAsBytes = null;221 ResponseMessage.BodyAsFile = filename;222 }223224 return this;225 }226227 /// <inheritdoc cref="IBodyResponseBuilder.WithBody(string, string, Encoding)"/>228 public IResponseBuilder WithBody(string body, string destination = BodyDestinationFormat.SameAsSource, Encoding 229 {230 Check.NotNull(body, nameof(body));231232 encoding = encoding ?? Encoding.UTF8;233234 ResponseMessage.BodyDestination = destination;235 ResponseMessage.BodyEncoding = encoding;236237 switch (destination)238 {239 case BodyDestinationFormat.Bytes:240 ResponseMessage.Body = null;241 ResponseMessage.BodyAsJson = null;242 ResponseMessage.BodyAsBytes = encoding.GetBytes(body);243 break;244245 case BodyDestinationFormat.Json:246 ResponseMessage.Body = null;247 ResponseMessage.BodyAsJson = JsonConvert.DeserializeObject(body);248 ResponseMessage.BodyAsBytes = null;249 break;250251 default:252 ResponseMessage.Body = body;253 ResponseMessage.BodyAsJson = null;254 ResponseMessage.BodyAsBytes = null;255 break;256 }257258 return this;259 }260261 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson"/>262 public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null)263 {264 Check.NotNull(body, nameof(body));265266 ResponseMessage.BodyDestination = null;267 ResponseMessage.BodyAsJson = body;268 ResponseMessage.BodyEncoding = encoding;81 /// <summary>82 /// Initializes a new instance of the <see cref="Response"/> class.83 /// </summary>84 /// <param name="responseMessage">85 /// The response.86 /// </param>87 private Response(ResponseMessage responseMessage)88 {89 ResponseMessage = responseMessage;90 }9192 /// <summary>93 /// The with status code.94 /// </summary>95 /// <param name="code">The code.</param>96 /// <returns>A <see cref="IResponseBuilder"/>.</returns>\97 [PublicAPI]98 public IResponseBuilder WithStatusCode(int code)99 {100 ResponseMessage.StatusCode = code;101 return this;102 }103104 /// <summary>105 /// The with status code.106 /// </summary>107 /// <param name="code">The code.</param>108 /// <returns>A <see cref="IResponseBuilder"/>.</returns>109 [PublicAPI]110 public IResponseBuilder WithStatusCode(HttpStatusCode code)111 {112 return WithStatusCode((int)code);113 }114115 /// <summary>116 /// The with Success status code (200).117 /// </summary>118 /// <returns>A <see cref="IResponseBuilder"/>.</returns>119 [PublicAPI]120 public IResponseBuilder WithSuccess()121 {122 return WithStatusCode((int)HttpStatusCode.OK);123 }124125 /// <summary>126 /// The with NotFound status code (404).127 /// </summary>128 /// <returns>The <see cref="IResponseBuilder"/>.</returns>129 [PublicAPI]130 public IResponseBuilder WithNotFound()131 {132 return WithStatusCode((int)HttpStatusCode.NotFound);133 }134135 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeader(string, string[])"/>136 public IResponseBuilder WithHeader(string name, params string[] values)137 {138 Check.NotNull(name, nameof(name));139140 ResponseMessage.AddHeader(name, values);141 return this;142 }143144 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, string})"/>145 public IResponseBuilder WithHeaders(IDictionary<string, string> headers)146 {147 Check.NotNull(headers, nameof(headers));148149 ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList<string>(head150 return this;151 }152153 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, string[]})"/>154 public IResponseBuilder WithHeaders(IDictionary<string, string[]> headers)155 {156 Check.NotNull(headers, nameof(headers));157158 ResponseMessage.Headers = headers.ToDictionary(header => header.Key, header => new WireMockList<string>(head159 return this;160 }161162 /// <inheritdoc cref="IHeadersResponseBuilder.WithHeaders(IDictionary{string, WireMockList{string}})"/>163 public IResponseBuilder WithHeaders(IDictionary<string, WireMockList<string>> headers)164 {165 ResponseMessage.Headers = headers;166 return this;167 }168169 /// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, string}, string, Encoding)"/>170 public IResponseBuilder WithBody(Func<RequestMessage, string> bodyFactory, string destination = BodyDestinationF171 {172 Check.NotNull(bodyFactory, nameof(bodyFactory));173174 return WithCallback(req => new ResponseMessage175 {176 Body = bodyFactory(req),177 BodyDestination = destination,178 BodyEncoding = encoding ?? Encoding.UTF8179 });180 }181182 /// <inheritdoc cref="IBodyResponseBuilder.WithBody(byte[], string, Encoding)"/>183 public IResponseBuilder WithBody(byte[] body, string destination = BodyDestinationFormat.SameAsSource, Encoding 184 {185 Check.NotNull(body, nameof(body));186187 ResponseMessage.BodyDestination = destination;188189 switch (destination)190 {191 case BodyDestinationFormat.String:192 var enc = encoding ?? Encoding.UTF8;193 ResponseMessage.BodyAsBytes = null;194 ResponseMessage.Body = enc.GetString(body);195 ResponseMessage.BodyEncoding = enc;196 break;197198 default:199 ResponseMessage.BodyAsBytes = body;200 ResponseMessage.BodyEncoding = null;201 break;202 }203204 return this;205 }206207 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromFile"/>208 public IResponseBuilder WithBodyFromFile(string filename, bool cache = true)209 {210 Check.NotNull(filename, nameof(filename));211212 ResponseMessage.BodyEncoding = null;213 ResponseMessage.BodyAsFileIsCached = cache;214215 if (cache)216 {217 ResponseMessage.Body = null;218 ResponseMessage.BodyAsBytes = File.ReadAllBytes(filename);219 ResponseMessage.BodyAsFile = null;220 }221 else222 {223 ResponseMessage.Body = null;224 ResponseMessage.BodyAsBytes = null;225 ResponseMessage.BodyAsFile = filename;226 }227228 return this;229 }230231 /// <inheritdoc cref="IBodyResponseBuilder.WithBody(string, string, Encoding)"/>232 public IResponseBuilder WithBody(string body, string destination = BodyDestinationFormat.SameAsSource, Encoding 233 {234 Check.NotNull(body, nameof(body));235236 encoding = encoding ?? Encoding.UTF8;237238 ResponseMessage.BodyDestination = destination;239 ResponseMessage.BodyEncoding = encoding;240241 switch (destination)242 {243 case BodyDestinationFormat.Bytes:244 ResponseMessage.Body = null;245 ResponseMessage.BodyAsJson = null;246 ResponseMessage.BodyAsBytes = encoding.GetBytes(body);247 break;248249 case BodyDestinationFormat.Json:250 ResponseMessage.Body = null;251 ResponseMessage.BodyAsJson = JsonConvert.DeserializeObject(body);252 ResponseMessage.BodyAsBytes = null;253 break;254255 default:256 ResponseMessage.Body = body;257 ResponseMessage.BodyAsJson = null;258 ResponseMessage.BodyAsBytes = null;259 break;260 }261262 return this;263 }264265 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, Encoding, bool?)"/>266 public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null, bool? indented = null)267 {268 Check.NotNull(body, nameof(body));269270 return this;271 }272273 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromBase64"/>274 public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null)275 {276 Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));270 ResponseMessage.BodyDestination = null;271 ResponseMessage.BodyAsJson = body;272 ResponseMessage.BodyEncoding = encoding;273 ResponseMessage.BodyAsJsonIndented = indented;274275 return this;276 }277278 encoding = encoding ?? Encoding.UTF8;279280 ResponseMessage.BodyDestination = null;281 ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));282 ResponseMessage.BodyEncoding = encoding;278 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, bool)"/>279 public IResponseBuilder WithBodyAsJson(object body, bool indented)280 {281 return WithBodyAsJson(body, null, indented);282 }283284 return this;285 }286287 /// <inheritdoc cref="ITransformResponseBuilder.WithTransformer"/>288 public IResponseBuilder WithTransformer()289 {290 UseTransformer = true;291 return this;292 }293294 /// <inheritdoc cref="IDelayResponseBuilder.WithDelay(TimeSpan)"/>295 public IResponseBuilder WithDelay(TimeSpan delay)296 {297 Check.Condition(delay, d => d > TimeSpan.Zero, nameof(delay));298299 Delay = delay;300 return this;301 }302303 /// <inheritdoc cref="IDelayResponseBuilder.WithDelay(int)"/>304 public IResponseBuilder WithDelay(int milliseconds)305 {306 return WithDelay(TimeSpan.FromMilliseconds(milliseconds));307 }308309 /// <inheritdoc cref="IProxyResponseBuilder.WithProxy(string, string)"/>310 public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)311 {312 Check.NotNullOrEmpty(proxyUrl, nameof(proxyUrl));284 /// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromBase64"/>285 public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null)286 {287 Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));288289 encoding = encoding ?? Encoding.UTF8;290291 ResponseMessage.BodyDestination = null;292 ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));293 ResponseMessage.BodyEncoding = encoding;294295 return this;296 }297298 /// <inheritdoc cref="ITransformResponseBuilder.WithTransformer"/>299 public IResponseBuilder WithTransformer()300 {301 UseTransformer = true;302 return this;303 }304305 /// <inheritdoc cref="IDelayResponseBuilder.WithDelay(TimeSpan)"/>306 public IResponseBuilder WithDelay(TimeSpan delay)307 {308 Check.Condition(delay, d => d > TimeSpan.Zero, nameof(delay));309310 Delay = delay;311 return this;312 }313314 ProxyUrl = proxyUrl;315 ClientX509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName;316 _httpClientForProxy = HttpClientHelper.CreateHttpClient(clientX509Certificate2ThumbprintOrSubjectName);317 return this;318 }314 /// <inheritdoc cref="IDelayResponseBuilder.WithDelay(int)"/>315 public IResponseBuilder WithDelay(int milliseconds)316 {317 return WithDelay(TimeSpan.FromMilliseconds(milliseconds));318 }319320 /// <inheritdoc cref="IProxyResponseBuilder.WithProxy(IProxyAndRecordSettings)"/>321 public IResponseBuilder WithProxy(IProxyAndRecordSettings settings)320 /// <inheritdoc cref="IProxyResponseBuilder.WithProxy(string, string)"/>321 public IResponseBuilder WithProxy(string proxyUrl, string clientX509Certificate2ThumbprintOrSubjectName = null)322 {323 Check.NotNull(settings, nameof(settings));323 Check.NotNullOrEmpty(proxyUrl, nameof(proxyUrl));324325 return WithProxy(settings.Url, settings.ClientX509Certificate2ThumbprintOrSubjectName);326 }327328 /// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>329 public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)330 {331 Check.NotNull(callbackHandler, nameof(callbackHandler));332333 Callback = callbackHandler;334335 return this;336 }337338 /// <summary>339 /// The provide response.340 /// </summary>341 /// <param name="requestMessage">The request.</param>342 /// <returns>The <see cref="ResponseMessage"/>.</returns>343 public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)344 {345 Check.NotNull(requestMessage, nameof(requestMessage));346347 if (Delay != null)348 {349 await Task.Delay(Delay.Value);350 }351352 if (ProxyUrl != null && _httpClientForProxy != null)353 {354 var requestUri = new Uri(requestMessage.Url);355 var proxyUri = new Uri(ProxyUrl);356 var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);325 ProxyUrl = proxyUrl;326 ClientX509Certificate2ThumbprintOrSubjectName = clientX509Certificate2ThumbprintOrSubjectName;327 _httpClientForProxy = HttpClientHelper.CreateHttpClient(clientX509Certificate2ThumbprintOrSubjectName);328 return this;329 }330331 /// <inheritdoc cref="IProxyResponseBuilder.WithProxy(IProxyAndRecordSettings)"/>332 public IResponseBuilder WithProxy(IProxyAndRecordSettings settings)333 {334 Check.NotNull(settings, nameof(settings));335336 return WithProxy(settings.Url, settings.ClientX509Certificate2ThumbprintOrSubjectName);337 }338339 /// <inheritdoc cref="ICallbackResponseBuilder.WithCallback"/>340 public IResponseBuilder WithCallback(Func<RequestMessage, ResponseMessage> callbackHandler)341 {342 Check.NotNull(callbackHandler, nameof(callbackHandler));343344 Callback = callbackHandler;345346 return this;347 }348349 /// <summary>350 /// The provide response.351 /// </summary>352 /// <param name="requestMessage">The request.</param>353 /// <returns>The <see cref="ResponseMessage"/>.</returns>354 public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)355 {356 Check.NotNull(requestMessage, nameof(requestMessage));357358 return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQ359 }360361 if (UseTransformer)362 {363 return ResponseMessageTransformer.Transform(requestMessage, ResponseMessage);364 }365366 if (Callback != null)367 {368 return Callback(requestMessage);369 }370371 return ResponseMessage;372 }373 }374}358 if (Delay != null)359 {360 await Task.Delay(Delay.Value);361 }362363 if (Callback != null)364 {365 var callbackResponseMessage = Callback(requestMessage);366367 // Copy StatusCode from ResponseMessage368 callbackResponseMessage.StatusCode = ResponseMessage.StatusCode;369370 // Copy Headers from ResponseMessage (if defined)371 if (ResponseMessage.Headers != null)372 {373 callbackResponseMessage.Headers = ResponseMessage.Headers;374 }375376 return callbackResponseMessage;377 }378379 if (ProxyUrl != null && _httpClientForProxy != null)380 {381 var requestUri = new Uri(requestMessage.Url);382 var proxyUri = new Uri(ProxyUrl);383 var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);384385 return await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQ386 }387388 if (UseTransformer)389 {390 return ResponseMessageTransformer.Transform(requestMessage, ResponseMessage);391 }392393 // Just return normal defined ResponseMessage394 return ResponseMessage;395 }396 }397}| Class: | WireMock.ResponseMessageBuilder |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\ResponseMessageBuilder.cs |
| Covered lines: | 11 |
| Uncovered lines: | 0 |
| Coverable lines: | 11 |
| Total lines: | 26 |
| Line coverage: | 100% |
| Branch coverage: | 50% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Create(...) | 0 | 0 | 1 | 0.5 |
| .cctor() | 0 | 0 | 1 | 0 |
| Class: | WireMock.Transformers.ResponseMessageTransformer |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Transformers\ResponseMessageTransformer.cs |
| Covered lines: | 78 |
| Uncovered lines: | 4 |
| Coverable lines: | 82 |
| Total lines: | 135 |
| Line coverage: | 95.1% |
| Branch coverage: | 92.8% |
10 /// <summary>11 /// Gets or sets the HTTP status.12 /// </summary>13 public int? StatusCode { get; set; }13 public int? StatusCode { get; set; }1415 /// <summary>16 /// Gets or sets the body destination (SameAsSource, String or Bytes).17 /// </summary>18 public string BodyDestination { get; set; }18 public string BodyDestination { get; set; }1920 /// <summary>21 /// Gets or sets the body.22 /// </summary>23 public string Body { get; set; }23 public string Body { get; set; }2425 /// <summary>26 /// Gets or sets the body.27 /// </summary>28 public string BodyFromBase64 { get; set; }28 public string BodyFromBase64 { get; set; }2930 /// <summary>31 /// Gets or sets the body (as JSON object).32 /// </summary>33 public object BodyAsJson { get; set; }33 public object BodyAsJson { get; set; }3435 /// <summary>36 /// Gets or sets the body (as bytearray).36 /// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTe37 /// </summary>38 public byte[] BodyAsBytes { get; set; }38 public bool? BodyAsJsonIndented { get; set; }3940 /// <summary>41 /// Gets or sets the body as a file.41 /// Gets or sets the body (as bytearray).42 /// </summary>43 public string BodyAsFile { get; set; }43 public byte[] BodyAsBytes { get; set; }4445 /// <summary>46 /// Is the body as file cached?46 /// Gets or sets the body as a file.47 /// </summary>48 public bool? BodyAsFileIsCached { get; set; }48 public string BodyAsFile { get; set; }4950 /// <summary>51 /// Gets or sets the body encoding.51 /// Is the body as file cached?52 /// </summary>53 public EncodingModel BodyEncoding { get; set; }53 public bool? BodyAsFileIsCached { get; set; }5455 /// <summary>56 /// Gets or sets a value indicating whether [use transformer].56 /// Gets or sets the body encoding.57 /// </summary>58 public bool UseTransformer { get; set; }58 public EncodingModel BodyEncoding { get; set; }5960 /// <summary>61 /// Gets or sets the headers.61 /// Gets or sets a value indicating whether [use transformer].62 /// </summary>63 public IDictionary<string, object> Headers { get; set; }63 public bool UseTransformer { get; set; }6465 /// <summary>66 /// Gets or sets the Headers (Raw).66 /// Gets or sets the headers.67 /// </summary>68 public string HeadersRaw { get; set; }68 public IDictionary<string, object> Headers { get; set; }6970 /// <summary>71 /// Gets or sets the delay in milliseconds.71 /// Gets or sets the Headers (Raw).72 /// </summary>73 public int? Delay { get; set; }73 public string HeadersRaw { get; set; }7475 /// <summary>76 /// Gets or sets the Proxy URL.76 /// Gets or sets the delay in milliseconds.77 /// </summary>78 public string ProxyUrl { get; set; }78 public int? Delay { get; set; }7980 /// <summary>81 /// The client X509Certificate2 Thumbprint or SubjectName to use.81 /// Gets or sets the Proxy URL.82 /// </summary>83 public string X509Certificate2ThumbprintOrSubjectName { get; set; }84 }85}83 public string ProxyUrl { get; set; }8485 /// <summary>86 /// The client X509Certificate2 Thumbprint or SubjectName to use.87 /// </summary>88 public string X509Certificate2ThumbprintOrSubjectName { get; set; }89 }90}16 private readonly string[] _patterns;17 private readonly SimMetricType _simMetricType;1819 /// <summary>20 /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.21 /// </summary>22 /// <param name="pattern">The pattern.</param>23 /// <param name="simMetricType">The SimMetric Type</param>24 public SimMetricsMatcher([NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : thi25 {26 }2728 /// <summary>29 /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.30 /// </summary>31 /// <param name="patterns">The patterns.</param>32 /// <param name="simMetricType">The SimMetric Type</param>33 public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein)34 {35 Check.NotNullOrEmpty(patterns, nameof(patterns));3637 _patterns = patterns;38 _simMetricType = simMetricType;39 }19 /// <inheritdoc cref="IMatcher.MatchBehaviour"/>20 public MatchBehaviour MatchBehaviour { get; }2122 /// <summary>23 /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.24 /// </summary>25 /// <param name="pattern">The pattern.</param>26 /// <param name="simMetricType">The SimMetric Type</param>27 public SimMetricsMatcher([NotNull] string pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : thi28 {29 }3031 /// <summary>32 /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.33 /// </summary>34 /// <param name="matchBehaviour">The match behaviour.</param>35 /// <param name="pattern">The pattern.</param>36 /// <param name="simMetricType">The SimMetric Type</param>37 public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string pattern, SimMetricType simMetricType = 38 {39 }4041 /// <inheritdoc cref="IStringMatcher.IsMatch"/>42 public double IsMatch(string input)43 {44 IStringMetric m = GetStringMetricType();4546 return MatchScores.ToScore(_patterns.Select(p => m.GetSimilarity(p, input)));47 }4849 private IStringMetric GetStringMetricType()50 {51 switch (_simMetricType)52 {53 case SimMetricType.BlockDistance:54 return new BlockDistance();55 case SimMetricType.ChapmanLengthDeviation:56 return new ChapmanLengthDeviation();57 case SimMetricType.CosineSimilarity:58 return new CosineSimilarity();59 case SimMetricType.DiceSimilarity:60 return new DiceSimilarity();61 case SimMetricType.EuclideanDistance:62 return new EuclideanDistance();63 case SimMetricType.JaccardSimilarity:64 return new JaccardSimilarity();65 case SimMetricType.Jaro:66 return new Jaro();67 case SimMetricType.JaroWinkler:68 return new JaroWinkler();69 case SimMetricType.MatchingCoefficient:70 return new MatchingCoefficient();71 case SimMetricType.MongeElkan:72 return new MongeElkan();73 case SimMetricType.NeedlemanWunch:74 return new NeedlemanWunch();75 case SimMetricType.OverlapCoefficient:76 return new OverlapCoefficient();77 case SimMetricType.QGramsDistance:78 return new QGramsDistance();79 case SimMetricType.SmithWaterman:80 return new SmithWaterman();81 case SimMetricType.SmithWatermanGotoh:82 return new SmithWatermanGotoh();83 case SimMetricType.SmithWatermanGotohWindowedAffine:84 return new SmithWatermanGotohWindowedAffine();85 case SimMetricType.ChapmanMeanLength:86 return new ChapmanMeanLength();87 default:88 return new Levenstein();89 }90 }9192 /// <inheritdoc cref="IStringMatcher.GetPatterns"/>93 public string[] GetPatterns()94 {95 return _patterns;96 }9798 /// <inheritdoc cref="IMatcher.GetName"/>99 public string GetName()100 {101 return $"SimMetricsMatcher.{_simMetricType}";102 }103 }104}41 /// <summary>42 /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.43 /// </summary>44 /// <param name="patterns">The patterns.</param>45 /// <param name="simMetricType">The SimMetric Type</param>46 public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : 47 {48 }4950 /// <summary>51 /// Initializes a new instance of the <see cref="SimMetricsMatcher"/> class.52 /// </summary>53 /// <param name="matchBehaviour">The match behaviour.</param>54 /// <param name="patterns">The patterns.</param>55 /// <param name="simMetricType">The SimMetric Type</param>56 public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] string[] patterns, SimMetricType simMetricType57 {58 Check.NotNullOrEmpty(patterns, nameof(patterns));5960 MatchBehaviour = matchBehaviour;61 _patterns = patterns;62 _simMetricType = simMetricType;63 }6465 /// <inheritdoc cref="IStringMatcher.IsMatch"/>66 public double IsMatch(string input)67 {68 IStringMetric m = GetStringMetricType();6970 return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => m.GetSimilarit71 }7273 private IStringMetric GetStringMetricType()74 {75 switch (_simMetricType)76 {77 case SimMetricType.BlockDistance:78 return new BlockDistance();79 case SimMetricType.ChapmanLengthDeviation:80 return new ChapmanLengthDeviation();81 case SimMetricType.CosineSimilarity:82 return new CosineSimilarity();83 case SimMetricType.DiceSimilarity:84 return new DiceSimilarity();85 case SimMetricType.EuclideanDistance:86 return new EuclideanDistance();87 case SimMetricType.JaccardSimilarity:88 return new JaccardSimilarity();89 case SimMetricType.Jaro:90 return new Jaro();91 case SimMetricType.JaroWinkler:92 return new JaroWinkler();93 case SimMetricType.MatchingCoefficient:94 return new MatchingCoefficient();95 case SimMetricType.MongeElkan:96 return new MongeElkan();97 case SimMetricType.NeedlemanWunch:98 return new NeedlemanWunch();99 case SimMetricType.OverlapCoefficient:100 return new OverlapCoefficient();101 case SimMetricType.QGramsDistance:102 return new QGramsDistance();103 case SimMetricType.SmithWaterman:104 return new SmithWaterman();105 case SimMetricType.SmithWatermanGotoh:106 return new SmithWatermanGotoh();107 case SimMetricType.SmithWatermanGotohWindowedAffine:108 return new SmithWatermanGotohWindowedAffine();109 case SimMetricType.ChapmanMeanLength:110 return new ChapmanMeanLength();111 default:112 return new Levenstein();113 }114 }115116 /// <inheritdoc cref="IStringMatcher.GetPatterns"/>117 public string[] GetPatterns()118 {119 return _patterns;120 }121122 /// <inheritdoc cref="IMatcher.Name"/>123 public string Name => $"SimMetricsMatcher.{_simMetricType}";124 }125}| Class: | WireMock.Admin.Mappings.StatusModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\StatusModel.cs |
| Covered lines: | 2 |
| Uncovered lines: | 0 |
| Coverable lines: | 2 |
| Total lines: | 20 |
| Line coverage: | 100% |
| Class: | WireMock.Models.UrlDetails |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Models\UrlDetails.cs |
| Covered lines: | 15 |
| Uncovered lines: | 0 |
| Coverable lines: | 15 |
| Total lines: | 51 |
| Line coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| Class: | WireMock.Admin.Mappings.UrlModel |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Admin\Mappings\UrlModel.cs |
| Covered lines: | 0 |
| Uncovered lines: | 1 |
| Coverable lines: | 1 |
| Total lines: | 13 |
| Line coverage: | 0% |
| Class: | WireMock.Util.UrlUtils |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Util\UrlUtils.cs |
| Covered lines: | 15 |
| Uncovered lines: | 0 |
| Coverable lines: | 15 |
| Total lines: | 38 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Parse(...) | 0 | 0 | 1 | 1 |
| RemoveFirst(...) | 0 | 0 | 1 | 1 |
| Class: | WireMock.Matchers.WildcardMatcher |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Matchers\WildcardMatcher.cs |
| Covered lines: | 17 |
| Uncovered lines: | 0 |
| Coverable lines: | 17 |
| Total lines: | 63 |
| Line coverage: | 100% |
| Branch coverage: | 100% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| GetPatterns() | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 0 |
| .ctor(...) | 0 | 0 | 1 | 1 |
| Class: | WireMock.Logging.WireMockConsoleLogger |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Logging\WireMockConsoleLogger.cs |
| Covered lines: | 0 |
| Uncovered lines: | 24 |
| Coverable lines: | 24 |
| Total lines: | 59 |
| Line coverage: | 0% |
| Branch coverage: | 0% |
13 /// <summary>14 /// Initializes a new instance of the <see cref="WireMockList{T}"/> class.15 /// </summary>16 public WireMockList()17 {18 }16 public WireMockList()17 {18 }1920 /// <summary>21 /// Initializes a new instance of the <see cref="WireMockList{T}"/> class.22 /// </summary>23 /// <param name="collection">The collection whose elements are copied to the new list.</param>24 public WireMockList(params T[] collection) : base(collection)25 {26 }24 public WireMockList(params T[] collection) : base(collection)25 {26 }2728 /// <summary>29 /// Initializes a new instance of the <see cref="WireMockList{T}"/> class.37 /// Returns a <see cref="string" /> that represents this instance.38 /// </summary>39 public override string ToString()40 {41 if (this != null && this.Any())42 return this.First().ToString();4344 return base.ToString();45 }46 }47}40 {41 return this.Any() ? this.First().ToString() : base.ToString();42 }43 }44}1using System;2using System.Threading.Tasks;3using WireMock.Logging;4using WireMock.Matchers.Request;5using System.Linq;6using WireMock.Matchers;7using WireMock.Util;8using Newtonsoft.Json;9using WireMock.Http;10#if !NETSTANDARD11using Microsoft.Owin;12#else13using Microsoft.AspNetCore.Http;14#endif1516namespace WireMock.Owin17{18#if !NETSTANDARD19 internal class WireMockMiddleware : OwinMiddleware20#else21 internal class WireMockMiddleware22#endif23 {24 private static readonly Task CompletedTask = Task.FromResult(false);25 private readonly WireMockMiddlewareOptions _options;2627 private readonly OwinRequestMapper _requestMapper = new OwinRequestMapper();28 private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();2930#if !NETSTANDARD31 public WireMockMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)32 {33 _options = options;34 }35#else36 public WireMockMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)37 {38 _options = options;39 }40#endif4142#if !NETSTANDARD43 public override async Task Invoke(IOwinContext ctx)44#else45 public async Task Invoke(HttpContext ctx)46#endif47 {48 var request = await _requestMapper.MapAsync(ctx.Request);4950 bool logRequest = false;51 ResponseMessage response = null;52 Mapping targetMapping = null;53 RequestMatchResult requestMatchResult = null;54 try55 {56 foreach (var mapping in _options.Mappings.Values.Where(m => m?.Scenario != null))57 {58 // Set start59 if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)60 {61 _options.Scenarios.Add(mapping.Scenario, null);62 }63 }6465 var mappings = _options.Mappings.Values66 .Select(m => new67 {68 Mapping = m,69 MatchResult = m.GetRequestMatchResult(request, m.Scenario != null && _options.Scenarios.Contains70 })71 .ToList();7273 if (_options.AllowPartialMapping)74 {75 var partialMappings = mappings76 .Where(pm => pm.Mapping.IsAdminInterface && pm.MatchResult.IsPerfectMatch || !pm.Mapping.IsAdmin77 .OrderBy(m => m.MatchResult)78 .ThenBy(m => m.Mapping.Priority)79 .ToList();8081 var bestPartialMatch = partialMappings.FirstOrDefault(pm => pm.MatchResult.AverageTotalScore > 0.0);8283 targetMapping = bestPartialMatch?.Mapping;84 requestMatchResult = bestPartialMatch?.MatchResult;85 }86 else87 {88 var perfectMatch = mappings89 .OrderBy(m => m.Mapping.Priority)90 .FirstOrDefault(m => m.MatchResult.IsPerfectMatch);9192 targetMapping = perfectMatch?.Mapping;93 requestMatchResult = perfectMatch?.MatchResult;94 }9596 if (targetMapping == null)97 {98 logRequest = true;99 _options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");100 response = new ResponseMessage { StatusCode = 404, Body = "No matching mapping found" };101 return;102 }103104 logRequest = !targetMapping.IsAdminInterface;105106 if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null)107 {108 bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<stri109 if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfec110 {111 _options.Logger.Error("HttpStatusCode set to 401");112 response = new ResponseMessage { StatusCode = 401 };113 return;114 }115 }116117 if (!targetMapping.IsAdminInterface && _options.RequestProcessingDelay > TimeSpan.Zero)118 {119 await Task.Delay(_options.RequestProcessingDelay.Value);120 }2using System.Collections.Generic;3using System.Threading.Tasks;4using WireMock.Logging;5using WireMock.Matchers.Request;6using System.Linq;7using WireMock.Matchers;8using WireMock.Util;9using Newtonsoft.Json;10using WireMock.Http;11using WireMock.Serialization;12#if !USE_ASPNETCORE13using Microsoft.Owin;14#else15using Microsoft.AspNetCore.Http;16#endif1718namespace WireMock.Owin19{20#if !USE_ASPNETCORE21 internal class WireMockMiddleware : OwinMiddleware22#else23 internal class WireMockMiddleware24#endif25 {26 private static readonly Task CompletedTask = Task.FromResult(false);27 private readonly WireMockMiddlewareOptions _options;2829 private readonly OwinRequestMapper _requestMapper = new OwinRequestMapper();30 private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();3132#if !USE_ASPNETCORE33 public WireMockMiddleware(OwinMiddleware next, WireMockMiddlewareOptions options) : base(next)34 {35 _options = options;36 }37#else38 public WireMockMiddleware(RequestDelegate next, WireMockMiddlewareOptions options)39 {40 _options = options;41 }42#endif4344#if !USE_ASPNETCORE45 public override async Task Invoke(IOwinContext ctx)46#else47 public async Task Invoke(HttpContext ctx)48#endif49 {50 var request = await _requestMapper.MapAsync(ctx.Request);5152 bool logRequest = false;53 ResponseMessage response = null;54 Mapping targetMapping = null;55 RequestMatchResult requestMatchResult = null;56 try57 {58 foreach (var mapping in _options.Mappings.Values.Where(m => m?.Scenario != null))59 {60 // Set start61 if (!_options.Scenarios.ContainsKey(mapping.Scenario) && mapping.IsStartState)62 {63 _options.Scenarios.TryAdd(mapping.Scenario, new ScenarioState64 {65 Name = mapping.Scenario66 });67 }68 }6970 var mappings = _options.Mappings.Values71 .Select(m => new72 {73 Mapping = m,74 MatchResult = m.GetRequestMatchResult(request, m.Scenario != null && _options.Scenarios.Contains75 })76 .ToList();7778 if (_options.AllowPartialMapping)79 {80 var partialMappings = mappings81 .Where(pm => pm.Mapping.IsAdminInterface && pm.MatchResult.IsPerfectMatch || !pm.Mapping.IsAdmin82 .OrderBy(m => m.MatchResult)83 .ThenBy(m => m.Mapping.Priority)84 .ToList();8586 var bestPartialMatch = partialMappings.FirstOrDefault(pm => pm.MatchResult.AverageTotalScore > 0.0);8788 targetMapping = bestPartialMatch?.Mapping;89 requestMatchResult = bestPartialMatch?.MatchResult;90 }91 else92 {93 var perfectMatch = mappings94 .OrderBy(m => m.Mapping.Priority)95 .FirstOrDefault(m => m.MatchResult.IsPerfectMatch);9697 targetMapping = perfectMatch?.Mapping;98 requestMatchResult = perfectMatch?.MatchResult;99 }100101 if (targetMapping == null)102 {103 logRequest = true;104 _options.Logger.Warn("HttpStatusCode set to 404 : No matching mapping found");105 response = ResponseMessageBuilder.Create("No matching mapping found", 404);106 return;107 }108109 logRequest = !targetMapping.IsAdminInterface;110111 if (targetMapping.IsAdminInterface && _options.AuthorizationMatcher != null)112 {113 bool present = request.Headers.TryGetValue(HttpKnownHeaderNames.Authorization, out WireMockList<stri114 if (!present || _options.AuthorizationMatcher.IsMatch(authorization.ToString()) < MatchScores.Perfec115 {116 _options.Logger.Error("HttpStatusCode set to 401");117 response = ResponseMessageBuilder.Create(null, 401);118 return;119 }120 }121122 response = await targetMapping.ResponseToAsync(request);123124 if (targetMapping.Scenario != null)125 {126 _options.Scenarios[targetMapping.Scenario] = targetMapping.NextState;127 }128 }129 catch (Exception ex)130 {131 _options.Logger.Error("HttpStatusCode set to 500");132 response = new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) };133 }134 finally135 {136 var log = new LogEntry137 {138 Guid = Guid.NewGuid(),139 RequestMessage = request,140 ResponseMessage = response,141 MappingGuid = targetMapping?.Guid,142 MappingTitle = targetMapping?.Title,143 RequestMatchResult = requestMatchResult144 };145146 LogRequest(log, logRequest);147148 await _responseMapper.MapAsync(response, ctx.Response);149 }150151 await CompletedTask;152 }153154 private void LogRequest(LogEntry entry, bool addRequest)155 {156 if (addRequest)157 {158 _options.LogEntries.Add(entry);159 }122 if (!targetMapping.IsAdminInterface && _options.RequestProcessingDelay > TimeSpan.Zero)123 {124 await Task.Delay(_options.RequestProcessingDelay.Value);125 }126127 response = await targetMapping.ResponseToAsync(request);128129 if (targetMapping.Scenario != null)130 {131 _options.Scenarios[targetMapping.Scenario].NextState = targetMapping.NextState;132 _options.Scenarios[targetMapping.Scenario].Started = true;133 _options.Scenarios[targetMapping.Scenario].Finished = targetMapping.NextState == null;134 }135 }136 catch (Exception ex)137 {138 _options.Logger.Error("HttpStatusCode set to 500");139 response = ResponseMessageBuilder.Create(JsonConvert.SerializeObject(ex), 500);140 }141 finally142 {143 var log = new LogEntry144 {145 Guid = Guid.NewGuid(),146 RequestMessage = request,147 ResponseMessage = response,148 MappingGuid = targetMapping?.Guid,149 MappingTitle = targetMapping?.Title,150 RequestMatchResult = requestMatchResult151 };152153 LogRequest(log, logRequest);154155 await _responseMapper.MapAsync(response, ctx.Response);156 }157158 await CompletedTask;159 }160161 if (_options.MaxRequestLogCount != null)162 {163 var amount = _options.LogEntries.Count - _options.MaxRequestLogCount.Value;164 for (int i = 0; i < amount; i++)165 {166 _options.LogEntries.RemoveAt(0);167 }168 }161 private void LogRequest(LogEntry entry, bool addRequest)162 {163 _options.Logger.DebugRequestResponse(LogEntryMapper.Map(entry), entry.RequestMessage.Path.StartsWith("/__adm164165 if (addRequest)166 {167 _options.LogEntries.Add(entry);168 }169170 if (_options.RequestLogExpirationDuration != null)171 {172 var checkTime = DateTime.Now.AddHours(-_options.RequestLogExpirationDuration.Value);173174 for (var i = _options.LogEntries.Count - 1; i >= 0; i--)175 {176 var le = _options.LogEntries[i];177 if (le.RequestMessage.DateTime <= checkTime)178 {179 _options.LogEntries.RemoveAt(i);180 }181 }182 }183 }184 }185}170 if (_options.MaxRequestLogCount != null)171 {172 var amount = _options.LogEntries.Count - _options.MaxRequestLogCount.Value;173 for (int i = 0; i < amount; i++)174 {175 _options.LogEntries.RemoveAt(0);176 }177 }178179 if (_options.RequestLogExpirationDuration != null)180 {181 var checkTime = DateTime.Now.AddHours(-_options.RequestLogExpirationDuration.Value);182183 for (var i = _options.LogEntries.Count - 1; i >= 0; i--)184 {185 var le = _options.LogEntries[i];186 if (le.RequestMessage.DateTime <= checkTime)187 {188 _options.LogEntries.RemoveAt(i);189 }190 }191 }192 }193 }194}| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| .ctor() | 1 | 0 | 100 | 100 |
| Class: | WireMock.Logging.WireMockNullLogger |
|---|---|
| Assembly: | WireMock.Net |
| File(s): | C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Logging\WireMockNullLogger.cs |
| Covered lines: | 8 |
| Uncovered lines: | 2 |
| Coverable lines: | 10 |
| Total lines: | 41 |
| Line coverage: | 80% |
| Method | Cyclomatic complexity | NPath complexity | Sequence coverage | Branch coverage |
|---|---|---|---|---|
| Debug(...) | 0 | 0 | 1 | 0 |
| Info(...) | 0 | 0 | 1 | 0 |
| Warn(...) | 0 | 0 | 1 | 0 |
| Error(...) | 0 | 0 | 0 | 0 |
| DebugRequestResponse(...) | 0 | 0 | 1 | 0 |
17 {18 private readonly string[] _patterns;1920 /// <summary>21 /// Initializes a new instance of the <see cref="XPathMatcher"/> class.22 /// </summary>23 /// <param name="patterns">The patterns.</param>24 public XPathMatcher([NotNull] params string[] patterns)25 {26 Check.NotNull(patterns, nameof(patterns));2728 _patterns = patterns;29 }20 /// <inheritdoc cref="IMatcher.MatchBehaviour"/>21 public MatchBehaviour MatchBehaviour { get; }2223 /// <summary>24 /// Initializes a new instance of the <see cref="XPathMatcher"/> class.25 /// </summary>26 /// <param name="patterns">The patterns.</param>27 public XPathMatcher([NotNull] params string[] patterns) : this(MatchBehaviour.AcceptOnMatch, patterns)28 {29 }3031 /// <inheritdoc cref="IStringMatcher.IsMatch"/>32 public double IsMatch(string input)33 {34 if (input == null)35 {36 return MatchScores.Mismatch;37 }3839 try40 {41 var nav = new XmlDocument { InnerXml = input }.CreateNavigator();42#if NETSTANDARD1_343 return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})"))));44#else45 return MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))));46#endif47 }48 catch (Exception)49 {50 return MatchScores.Mismatch;51 }52 }5354 /// <inheritdoc cref="IStringMatcher.GetPatterns"/>55 public string[] GetPatterns()56 {57 return _patterns;58 }5960 /// <inheritdoc cref="IMatcher.GetName"/>61 public string GetName()62 {63 return "XPathMatcher";64 }65 }66}31 /// <summary>32 /// Initializes a new instance of the <see cref="XPathMatcher"/> class.33 /// </summary>34 /// <param name="matchBehaviour">The match behaviour.</param>35 /// <param name="patterns">The patterns.</param>36 public XPathMatcher(MatchBehaviour matchBehaviour, [NotNull] params string[] patterns)37 {38 Check.NotNull(patterns, nameof(patterns));3940 MatchBehaviour = matchBehaviour;41 _patterns = patterns;42 }4344 /// <inheritdoc cref="IStringMatcher.IsMatch"/>45 public double IsMatch(string input)46 {47 double match = MatchScores.Mismatch;48 if (input != null)49 {50 try51 {52 var nav = new XmlDocument { InnerXml = input }.CreateNavigator();53#if NETSTANDARD1_354 match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.Evaluate($"boolean({p})"))));55#else56 match = MatchScores.ToScore(_patterns.Select(p => true.Equals(nav.XPath2Evaluate($"boolean({p})"))))57#endif58 }59 catch (Exception)60 {61 // just ignore exception62 }63 }6465 return MatchBehaviourHelper.Convert(MatchBehaviour, match);66 }6768 /// <inheritdoc cref="IStringMatcher.GetPatterns"/>69 public string[] GetPatterns()70 {71 return _patterns;72 }7374 /// <inheritdoc cref="IMatcher.Name"/>75 public string Name => "XPathMatcher";76 }77}