mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-05-10 09:50:19 +02:00
Compare commits
5 Commits
1.5.32
...
stef-Ignor
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dabe3a2a10 | ||
|
|
b609191095 | ||
|
|
b1ae9aaf46 | ||
|
|
ad3ef83c5e | ||
|
|
35ffbbc7d9 |
28
CHANGELOG.md
28
CHANGELOG.md
@@ -1,27 +1,3 @@
|
|||||||
# 1.5.32 (15 July 2023)
|
|
||||||
- [#966](https://github.com/WireMock-Net/WireMock.Net/pull/966) - Fixed JsonPathMatcher to match nested objects [bug] contributed by [StefH](https://github.com/StefH)
|
|
||||||
- [#965](https://github.com/WireMock-Net/WireMock.Net/issues/965) - JsonPathMatcher does not match json body nested objects [bug]
|
|
||||||
- [#967](https://github.com/WireMock-Net/WireMock.Net/issues/967) - ⭐10 million downloads ! ⭐ [feature]
|
|
||||||
|
|
||||||
# 1.5.31 (08 July 2023)
|
|
||||||
- [#964](https://github.com/WireMock-Net/WireMock.Net/pull/964) - Add GraphQL Schema matching [feature] contributed by [StefH](https://github.com/StefH)
|
|
||||||
|
|
||||||
# 1.5.30 (28 June 2023)
|
|
||||||
- [#959](https://github.com/WireMock-Net/WireMock.Net/pull/959) - Fixed logic for FluentAssertions WithHeader [bug] contributed by [StefH](https://github.com/StefH)
|
|
||||||
- [#961](https://github.com/WireMock-Net/WireMock.Net/pull/961) - Add unit-test for Param MatcherModel LinqMatcher [test] contributed by [StefH](https://github.com/StefH)
|
|
||||||
- [#962](https://github.com/WireMock-Net/WireMock.Net/pull/962) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.Console.Net472.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
|
||||||
- [#963](https://github.com/WireMock-Net/WireMock.Net/pull/963) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
|
||||||
- [#958](https://github.com/WireMock-Net/WireMock.Net/issues/958) - [FluentAssertions] Should().HaveReceivedACall().WithHeader() only checks the first header with the matching key. [bug]
|
|
||||||
|
|
||||||
# 1.5.29 (22 June 2023)
|
|
||||||
- [#954](https://github.com/WireMock-Net/WireMock.Net/pull/954) - Support setting WireMockServerSettings via Environment [feature] contributed by [StefH](https://github.com/StefH)
|
|
||||||
- [#955](https://github.com/WireMock-Net/WireMock.Net/pull/955) - Fix some SonarCloud issues [refactor] contributed by [StefH](https://github.com/StefH)
|
|
||||||
- [#953](https://github.com/WireMock-Net/WireMock.Net/issues/953) - How to use environment variable [feature]
|
|
||||||
|
|
||||||
# 1.5.28 (11 June 2023)
|
|
||||||
- [#948](https://github.com/WireMock-Net/WireMock.Net/pull/948) - WireMock.Net.Testcontainers [feature] contributed by [StefH](https://github.com/StefH)
|
|
||||||
- [#951](https://github.com/WireMock-Net/WireMock.Net/pull/951) - Allow setting the Content-Length header for a HTTP method HEAD [feature] contributed by [StefH](https://github.com/StefH)
|
|
||||||
|
|
||||||
# 1.5.27 (03 June 2023)
|
# 1.5.27 (03 June 2023)
|
||||||
- [#946](https://github.com/WireMock-Net/WireMock.Net/pull/946) - Add warning logging when sending a request to a Webhook does not return status 200 [feature] contributed by [StefH](https://github.com/StefH)
|
- [#946](https://github.com/WireMock-Net/WireMock.Net/pull/946) - Add warning logging when sending a request to a Webhook does not return status 200 [feature] contributed by [StefH](https://github.com/StefH)
|
||||||
- [#949](https://github.com/WireMock-Net/WireMock.Net/pull/949) - Add ".NET Framework 4.7" to WireMock.Net.FluentAssertions [feature] contributed by [StefH](https://github.com/StefH)
|
- [#949](https://github.com/WireMock-Net/WireMock.Net/pull/949) - Add ".NET Framework 4.7" to WireMock.Net.FluentAssertions [feature] contributed by [StefH](https://github.com/StefH)
|
||||||
@@ -970,7 +946,7 @@
|
|||||||
- [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files [feature]
|
- [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files [feature]
|
||||||
|
|
||||||
# 1.0.2.13 (23 January 2018)
|
# 1.0.2.13 (23 January 2018)
|
||||||
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [volodymyr-fed](https://github.com/volodymyr-fed)
|
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [vladimir-fed](https://github.com/vladimir-fed)
|
||||||
- [#57](https://github.com/WireMock-Net/WireMock.Net/issues/57) - ProxyAndRecord does not save query-parameters, headers and body [bug]
|
- [#57](https://github.com/WireMock-Net/WireMock.Net/issues/57) - ProxyAndRecord does not save query-parameters, headers and body [bug]
|
||||||
- [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost.
|
- [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost.
|
||||||
|
|
||||||
@@ -997,7 +973,7 @@
|
|||||||
|
|
||||||
# 1.0.2.7 (18 November 2017)
|
# 1.0.2.7 (18 November 2017)
|
||||||
- [#62](https://github.com/WireMock-Net/WireMock.Net/pull/62) - Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating contributed by [alastairtree](https://github.com/alastairtree)
|
- [#62](https://github.com/WireMock-Net/WireMock.Net/pull/62) - Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating contributed by [alastairtree](https://github.com/alastairtree)
|
||||||
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [volodymyr-fed](https://github.com/volodymyr-fed)
|
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [vladimir-fed](https://github.com/vladimir-fed)
|
||||||
- [#27](https://github.com/WireMock-Net/WireMock.Net/issues/27) - New feature: Record and Save
|
- [#27](https://github.com/WireMock-Net/WireMock.Net/issues/27) - New feature: Record and Save
|
||||||
- [#42](https://github.com/WireMock-Net/WireMock.Net/issues/42) - Enhancement - Save/load request logs to/from disk [feature]
|
- [#42](https://github.com/WireMock-Net/WireMock.Net/issues/42) - Enhancement - Save/load request logs to/from disk [feature]
|
||||||
- [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline
|
- [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>1.5.32</VersionPrefix>
|
<VersionPrefix>1.5.27</VersionPrefix>
|
||||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
rem https://github.com/StefH/GitHubReleaseNotes
|
rem https://github.com/StefH/GitHubReleaseNotes
|
||||||
|
|
||||||
SET version=1.5.32
|
SET version=1.5.27
|
||||||
|
|
||||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%
|
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# 1.5.32 (15 July 2023)
|
# 1.5.27 (03 June 2023)
|
||||||
- #966 Fixed JsonPathMatcher to match nested objects [bug]
|
- #946 Add warning logging when sending a request to a Webhook does not return status 200 [feature]
|
||||||
- #965 JsonPathMatcher does not match json body nested objects [bug]
|
- #949 Add ".NET Framework 4.7" to WireMock.Net.FluentAssertions [feature]
|
||||||
- #967 ⭐10 million downloads ! ⭐ [feature]
|
- #928 TypeLoadException when using WithHeader method. [bug]
|
||||||
|
- #945 Webhook logging [feature]
|
||||||
|
|
||||||
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
||||||
@@ -42,7 +42,6 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
|
|||||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||||
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
||||||
| **WireMock.Net.Testcontainers** | [](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
|
|
||||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||||
|
|
||||||
|
|
||||||
@@ -69,15 +68,13 @@ WireMock.Net can be used in several ways:
|
|||||||
You can use your favorite test framework and use WireMock within your tests, see
|
You can use your favorite test framework and use WireMock within your tests, see
|
||||||
[Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests).
|
[Wiki : UnitTesting](https://github.com/StefH/WireMock.Net/wiki/Using-WireMock-in-UnitTests).
|
||||||
|
|
||||||
### Unit/Integration Testing using Testcontainers.DotNet
|
|
||||||
You can use [Wiki : WireMock.Net.Testcontainers](https://github.com/WireMock-Net/WireMock.Net/wiki/Using-WireMock.Net.Testcontainers) to build a WireMock.Net Docker container which can be used in Unit/Integration testing.
|
|
||||||
|
|
||||||
### As a dotnet tool
|
### As a dotnet tool
|
||||||
It's simple to install WireMock.Net as (global) dotnet tool, see [Wiki : dotnet tool](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-dotnet-tool).
|
It's simple to install WireMock.Net as (global) dotnet tool, see [Wiki : dotnet tool](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-dotnet-tool).
|
||||||
|
|
||||||
### As standalone process / console application
|
### As standalone process / console application
|
||||||
This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process).
|
This is quite straight forward to launch a mock server within a console application, see [Wiki : Standalone Process](https://github.com/StefH/WireMock.Net/wiki/WireMock-as-a-standalone-process).
|
||||||
|
|
||||||
|
|
||||||
### As a Windows Service
|
### As a Windows Service
|
||||||
You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service).
|
You can also run WireMock.Net as a Windows Service, follow this [WireMock-as-a-Windows-Service](https://github.com/WireMock-Net/WireMock.Net/wiki/WireMock-as-a-Windows-Service).
|
||||||
|
|
||||||
|
|||||||
@@ -111,10 +111,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueExample",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Testcontainers", "src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj", "{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.TestcontainersExample", "examples\WireMock.Net.TestcontainersExample\WireMock.Net.TestcontainersExample.csproj", "{56A38798-C48B-4A4A-B805-071E05C02CE1}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -269,14 +265,6 @@ Global
|
|||||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{ADB557D8-D66B-4387-912B-3F73E290B478}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.Build.0 = Release|Any CPU
|
{ADB557D8-D66B-4387-912B-3F73E290B478}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{56A38798-C48B-4A4A-B805-071E05C02CE1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -321,8 +309,6 @@ Global
|
|||||||
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
{7C2A9DE8-C89F-4841-9058-6B9BF81E5E34} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||||
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
{BAA9EC2A-874B-45CE-8E51-A73622DC7F3D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||||
{ADB557D8-D66B-4387-912B-3F73E290B478} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
{ADB557D8-D66B-4387-912B-3F73E290B478} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||||
{12B016A5-9D8B-4EFE-96C2-CA51BE43367D} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
|
||||||
{56A38798-C48B-4A4A-B805-071E05C02CE1} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||||
|
|||||||
@@ -10,11 +10,9 @@
|
|||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IP/@EntryIndexedValue">IP</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD5</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD5</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OPTIONS/@EntryIndexedValue">OPTIONS</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OPTIONS/@EntryIndexedValue">OPTIONS</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OS/@EntryIndexedValue">OS</s:String>
|
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PATCH/@EntryIndexedValue">PATCH</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PATCH/@EntryIndexedValue">PATCH</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=POST/@EntryIndexedValue">POST</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=POST/@EntryIndexedValue">POST</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PUT/@EntryIndexedValue">PUT</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PUT/@EntryIndexedValue">PUT</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QL/@EntryIndexedValue">QL</s:String>
|
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RSA/@EntryIndexedValue">RSA</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RSA/@EntryIndexedValue">RSA</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String>
|
||||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String>
|
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String>
|
||||||
@@ -34,7 +32,6 @@
|
|||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Raml/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Raml/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=randomizer/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=randomizer/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scriban/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Scriban/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=sheyenrath/@EntryIndexedValue">True</s:Boolean>
|
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sigil/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sigil/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=templated/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/UserDictionary/Words/=templated/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@@ -27,8 +27,10 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||||
|
<!--<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />-->
|
||||||
<PackageReference Include="log4net" Version="2.0.15" />
|
<PackageReference Include="log4net" Version="2.0.15" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -42,36 +42,6 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
|
|
||||||
public static class MainApp
|
public static class MainApp
|
||||||
{
|
{
|
||||||
private const string TestSchema = @"
|
|
||||||
input MessageInput {
|
|
||||||
content: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Message {
|
|
||||||
id: ID!
|
|
||||||
content: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mutation {
|
|
||||||
createMessage(input: MessageInput): Message
|
|
||||||
updateMessage(id: ID!, input: MessageInput): Message
|
|
||||||
}
|
|
||||||
|
|
||||||
type Query {
|
|
||||||
greeting:String
|
|
||||||
students:[Student]
|
|
||||||
studentById(id:ID!):Student
|
|
||||||
}
|
|
||||||
|
|
||||||
type Student {
|
|
||||||
id:ID!
|
|
||||||
firstName:String
|
|
||||||
lastName:String
|
|
||||||
fullName:String
|
|
||||||
}";
|
|
||||||
|
|
||||||
public static void Run()
|
public static void Run()
|
||||||
{
|
{
|
||||||
var mappingBuilder = new MappingBuilder();
|
var mappingBuilder = new MappingBuilder();
|
||||||
@@ -167,16 +137,6 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
|
|
||||||
// server.AllowPartialMapping();
|
// server.AllowPartialMapping();
|
||||||
|
|
||||||
server
|
|
||||||
.Given(Request.Create()
|
|
||||||
.WithPath("/graphql")
|
|
||||||
.UsingPost()
|
|
||||||
.WithGraphQLSchema(TestSchema)
|
|
||||||
)
|
|
||||||
.RespondWith(Response.Create()
|
|
||||||
.WithBody("GraphQL is ok")
|
|
||||||
);
|
|
||||||
|
|
||||||
// 400 ms
|
// 400 ms
|
||||||
server
|
server
|
||||||
.Given(Request.Create()
|
.Given(Request.Create()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="AnyOf" version="0.3.0" targetFramework="net472" />
|
<package id="AnyOf" version="0.3.0" targetFramework="net472" />
|
||||||
<package id="Fare" version="2.2.1" targetFramework="net472" />
|
<package id="Fare" version="2.2.1" targetFramework="net472" />
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
<package id="System.Diagnostics.DiagnosticSource" version="4.5.0" targetFramework="net472" />
|
<package id="System.Diagnostics.DiagnosticSource" version="4.5.0" targetFramework="net472" />
|
||||||
<package id="System.IdentityModel.Tokens.Jwt" version="6.25.0" targetFramework="net472" />
|
<package id="System.IdentityModel.Tokens.Jwt" version="6.25.0" targetFramework="net472" />
|
||||||
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net472" />
|
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net472" />
|
||||||
<package id="System.Linq.Dynamic.Core" version="1.3.0" targetFramework="net472" />
|
<package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net472" />
|
||||||
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
|
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
|
||||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
|
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
|
||||||
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net472" />
|
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net472" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using WireMock.Net.OpenApiParser.Types;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ class Program
|
|||||||
private static void RunMockServerWithDynamicExampleGeneration()
|
private static void RunMockServerWithDynamicExampleGeneration()
|
||||||
{
|
{
|
||||||
// Run your mocking framework specifying your Example Values generator class.
|
// Run your mocking framework specifying your Example Values generator class.
|
||||||
var serverCustomer_V2_json = Run.RunServer(Path.Combine(Folder, "Swagger_Customer_V2.0.json"), "http://localhost:8090/", true, new DynamicDataGeneration(), Types.ExampleValueType.Value, Types.ExampleValueType.Value);
|
var serverCustomer_V2_json = Run.RunServer(Path.Combine(Folder, "Swagger_Customer_V2.0.json"), "http://localhost:8090/", true, new DynamicDataGeneration(), ExampleValueType.Value, ExampleValueType.Value);
|
||||||
Console.WriteLine("Press any key to stop the servers");
|
Console.WriteLine("Press any key to stop the servers");
|
||||||
|
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ static class Program
|
|||||||
|
|
||||||
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
|
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
|
||||||
|
|
||||||
if (!WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, new WireMockLog4NetLogger()))
|
if (!WireMockServerSettingsParser.TryParseArguments(args, out var settings, new WireMockLog4NetLogger()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
|
<package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
|
||||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net461" />
|
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net461" />
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
<package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" />
|
<package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" />
|
||||||
<package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net461" />
|
<package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net461" />
|
||||||
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net461" />
|
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net461" />
|
||||||
<package id="System.Linq.Dynamic.Core" version="1.3.0" targetFramework="net461" />
|
<package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net461" />
|
||||||
<package id="System.Memory" version="4.5.4" targetFramework="net461" />
|
<package id="System.Memory" version="4.5.4" targetFramework="net461" />
|
||||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
|
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
|
||||||
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net461" />
|
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net461" />
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using Testcontainers.MsSql;
|
|
||||||
using WireMock.Net.Testcontainers;
|
|
||||||
|
|
||||||
namespace WireMock.Net.TestcontainersExample;
|
|
||||||
|
|
||||||
internal class Program
|
|
||||||
{
|
|
||||||
private static async Task Main(string[] args)
|
|
||||||
{
|
|
||||||
var container = new WireMockContainerBuilder()
|
|
||||||
.WithAdminUserNameAndPassword("x", "y")
|
|
||||||
.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings")
|
|
||||||
.WithWatchStaticMappings(true)
|
|
||||||
.WithAutoRemove(true)
|
|
||||||
.WithCleanUp(true)
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
await container.StartAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false);
|
|
||||||
Console.WriteLine("logs = " + logs.Stdout);
|
|
||||||
|
|
||||||
var restEaseApiClient = container.CreateWireMockAdminClient();
|
|
||||||
|
|
||||||
var settings = await restEaseApiClient.GetSettingsAsync();
|
|
||||||
Console.WriteLine("settings = " + JsonConvert.SerializeObject(settings, Formatting.Indented));
|
|
||||||
|
|
||||||
var mappings = await restEaseApiClient.GetMappingsAsync();
|
|
||||||
Console.WriteLine("mappings = " + JsonConvert.SerializeObject(mappings, Formatting.Indented));
|
|
||||||
|
|
||||||
var client = container.CreateClient();
|
|
||||||
var result = await client.GetStringAsync("/static/mapping");
|
|
||||||
Console.WriteLine("result = " + result);
|
|
||||||
|
|
||||||
await container.StopAsync();
|
|
||||||
|
|
||||||
var sql = new MsSqlBuilder()
|
|
||||||
.WithAutoRemove(true)
|
|
||||||
.WithCleanUp(true)
|
|
||||||
.Build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Testcontainers.MsSql" Version="3.2.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -149,15 +149,15 @@ public class WireMockAssertions
|
|||||||
|
|
||||||
using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)"))
|
using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)"))
|
||||||
{
|
{
|
||||||
var matchingHeaderValues = _headers.Where(h => h.Key == expectedKey).SelectMany(h => h.Value.ToArray()).ToArray();
|
var headerValues = _headers.First(h => h.Key == expectedKey).Value;
|
||||||
|
|
||||||
if (expectedValues.Length == 1)
|
if (expectedValues.Length == 1)
|
||||||
{
|
{
|
||||||
matchingHeaderValues.Should().Contain(expectedValues.First(), because, becauseArgs);
|
headerValues.Should().Contain(expectedValues.First(), because, becauseArgs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var trimmedHeaderValues = string.Join(",", matchingHeaderValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
|
var trimmedHeaderValues = string.Join(",", headerValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
|
||||||
foreach (var expectedValue in expectedValues)
|
foreach (var expectedValue in expectedValues)
|
||||||
{
|
{
|
||||||
trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs);
|
trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs);
|
||||||
|
|||||||
@@ -23,12 +23,14 @@ internal class OpenApiPathsMapper
|
|||||||
private const string HeaderContentType = "Content-Type";
|
private const string HeaderContentType = "Content-Type";
|
||||||
|
|
||||||
private readonly WireMockOpenApiParserSettings _settings;
|
private readonly WireMockOpenApiParserSettings _settings;
|
||||||
private readonly ExampleValueGenerator _exampleValueGenerator;
|
private readonly IExampleValueGenerator _exampleValueGenerator;
|
||||||
|
private readonly IExampleValueGenerator _regexExampleValueGenerator;
|
||||||
|
|
||||||
public OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
public OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||||
{
|
{
|
||||||
_settings = Guard.NotNull(settings);
|
_settings = Guard.NotNull(settings);
|
||||||
_exampleValueGenerator = new ExampleValueGenerator(settings);
|
_exampleValueGenerator = new ExampleValueGenerator(settings);
|
||||||
|
_regexExampleValueGenerator = new RegexExampleValueGenerator(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<MappingModel> ToMappingModels(OpenApiPaths? paths, IList<OpenApiServer> servers)
|
public IReadOnlyList<MappingModel> ToMappingModels(OpenApiPaths? paths, IList<OpenApiServer> servers)
|
||||||
@@ -37,18 +39,7 @@ internal class OpenApiPathsMapper
|
|||||||
.OrderBy(p => p.Key)
|
.OrderBy(p => p.Key)
|
||||||
.Select(p => MapPath(p.Key, p.Value, servers))
|
.Select(p => MapPath(p.Key, p.Value, servers))
|
||||||
.SelectMany(x => x)
|
.SelectMany(x => x)
|
||||||
.ToArray() ??
|
.ToArray() ?? Array.Empty<MappingModel>();
|
||||||
Array.Empty<MappingModel>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private IReadOnlyList<MappingModel> MapPaths(OpenApiPaths? paths, IList<OpenApiServer> servers)
|
|
||||||
{
|
|
||||||
return paths?
|
|
||||||
.OrderBy(p => p.Key)
|
|
||||||
.Select(p => MapPath(p.Key, p.Value, servers))
|
|
||||||
.SelectMany(x => x)
|
|
||||||
.ToArray() ??
|
|
||||||
Array.Empty<MappingModel>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IReadOnlyList<MappingModel> MapPath(string path, OpenApiPathItem pathItem, IList<OpenApiServer> servers)
|
private IReadOnlyList<MappingModel> MapPath(string path, OpenApiPathItem pathItem, IList<OpenApiServer> servers)
|
||||||
@@ -280,54 +271,19 @@ internal class OpenApiPathsMapper
|
|||||||
return newPath;
|
return newPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string MapBasePath(IList<OpenApiServer>? servers)
|
|
||||||
{
|
|
||||||
if (servers == null || servers.Count == 0)
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenApiServer server = servers.First();
|
|
||||||
if (Uri.TryCreate(server.Url, UriKind.RelativeOrAbsolute, out Uri uriResult))
|
|
||||||
{
|
|
||||||
return uriResult.IsAbsoluteUri ? uriResult.AbsolutePath : uriResult.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JToken? MapOpenApiAnyToJToken(IOpenApiAny? any)
|
|
||||||
{
|
|
||||||
if (any == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
using var outputString = new StringWriter();
|
|
||||||
var writer = new OpenApiJsonWriter(outputString);
|
|
||||||
any.Write(writer, OpenApiSpecVersion.OpenApi3_0);
|
|
||||||
|
|
||||||
if (any.AnyType == AnyType.Array)
|
|
||||||
{
|
|
||||||
return JArray.Parse(outputString.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return JObject.Parse(outputString.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IDictionary<string, object>? MapHeaders(string? responseContentType, IDictionary<string, OpenApiHeader>? headers)
|
private IDictionary<string, object>? MapHeaders(string? responseContentType, IDictionary<string, OpenApiHeader>? headers)
|
||||||
{
|
{
|
||||||
var mappedHeaders = headers?.ToDictionary(
|
var mappedHeaders = headers?.ToDictionary(
|
||||||
item => item.Key,
|
item => item.Key,
|
||||||
_ => GetExampleMatcherModel(null, _settings.HeaderPatternToUse).Pattern!
|
_ => GetExampleMatcherModel(null, _settings.HeaderPatternToUse).Pattern!
|
||||||
) ?? new Dictionary<string, object>();
|
);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(responseContentType))
|
if (!string.IsNullOrEmpty(responseContentType))
|
||||||
{
|
{
|
||||||
mappedHeaders.TryAdd(HeaderContentType, responseContentType!);
|
mappedHeaders.TryAdd(HeaderContentType, responseContentType!);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mappedHeaders.Keys.Any() ? mappedHeaders : null;
|
return mappedHeaders?.Keys.Any() == true ? mappedHeaders : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IList<ParamModel>? MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters)
|
private IList<ParamModel>? MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters)
|
||||||
@@ -366,28 +322,38 @@ internal class OpenApiPathsMapper
|
|||||||
return list.Any() ? list : null;
|
return list.Any() ? list : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MatcherModel GetExampleMatcherModel(OpenApiSchema? schema, ExampleValueType type)
|
private MatcherModel GetExampleMatcherModel(OpenApiSchema? schema, ExampleValueType exampleValueType)
|
||||||
{
|
{
|
||||||
return type switch
|
return exampleValueType switch
|
||||||
{
|
{
|
||||||
ExampleValueType.Value => new MatcherModel
|
ExampleValueType.Value => new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "ExactMatcher",
|
Name = "ExactMatcher",
|
||||||
Pattern = GetExampleValueAsStringForSchemaType(schema),
|
Pattern = GetExampleValueAsStringForSchemaType(schema, exampleValueType),
|
||||||
|
IgnoreCase = _settings.IgnoreCaseExampleValues
|
||||||
|
},
|
||||||
|
|
||||||
|
ExampleValueType.Regex => new MatcherModel
|
||||||
|
{
|
||||||
|
Name = "RegexMatcher",
|
||||||
|
Pattern = GetExampleValueAsStringForSchemaType(schema, exampleValueType),
|
||||||
IgnoreCase = _settings.IgnoreCaseExampleValues
|
IgnoreCase = _settings.IgnoreCaseExampleValues
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => new MatcherModel
|
_ => new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "WildcardMatcher",
|
Name = "WildcardMatcher",
|
||||||
Pattern = "*"
|
Pattern = "*",
|
||||||
|
IgnoreCase = _settings.IgnoreCaseExampleValues
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetExampleValueAsStringForSchemaType(OpenApiSchema? schema)
|
private string GetExampleValueAsStringForSchemaType(OpenApiSchema? schema, ExampleValueType exampleValueType)
|
||||||
{
|
{
|
||||||
var value = _exampleValueGenerator.GetExampleValue(schema);
|
var value = exampleValueType == ExampleValueType.Regex ?
|
||||||
|
_regexExampleValueGenerator.GetExampleValue(schema) :
|
||||||
|
_exampleValueGenerator.GetExampleValue(schema);
|
||||||
|
|
||||||
return value switch
|
return value switch
|
||||||
{
|
{
|
||||||
@@ -396,4 +362,39 @@ internal class OpenApiPathsMapper
|
|||||||
_ => value.ToString(),
|
_ => value.ToString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string MapBasePath(IList<OpenApiServer>? servers)
|
||||||
|
{
|
||||||
|
if (servers == null || servers.Count == 0)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var server = servers.First();
|
||||||
|
if (Uri.TryCreate(server.Url, UriKind.RelativeOrAbsolute, out Uri uriResult))
|
||||||
|
{
|
||||||
|
return uriResult.IsAbsoluteUri ? uriResult.AbsolutePath : uriResult.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JToken? MapOpenApiAnyToJToken(IOpenApiAny? any)
|
||||||
|
{
|
||||||
|
if (any == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
using var outputString = new StringWriter();
|
||||||
|
var writer = new OpenApiJsonWriter(outputString);
|
||||||
|
any.Write(writer, OpenApiSpecVersion.OpenApi3_0);
|
||||||
|
|
||||||
|
if (any.AnyType == AnyType.Array)
|
||||||
|
{
|
||||||
|
return JArray.Parse(outputString.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return JObject.Parse(outputString.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
namespace WireMock.Net.OpenApiParser.Types;
|
namespace WireMock.Net.OpenApiParser.Types;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The example value to use
|
/// The (example) value pattern to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum ExampleValueType
|
public enum ExampleValueType
|
||||||
{
|
{
|
||||||
@@ -12,6 +12,11 @@ public enum ExampleValueType
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Value,
|
Value,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Build a Regex based on the SchemaType.
|
||||||
|
/// </summary>
|
||||||
|
Regex,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Just use a Wildcard (*) character.
|
/// Just use a Wildcard (*) character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using WireMock.Net.OpenApiParser.Types;
|
|||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser.Utils;
|
namespace WireMock.Net.OpenApiParser.Utils;
|
||||||
|
|
||||||
internal class ExampleValueGenerator
|
internal class ExampleValueGenerator : IExampleValueGenerator
|
||||||
{
|
{
|
||||||
private readonly IWireMockOpenApiParserExampleValues _exampleValues;
|
private readonly IWireMockOpenApiParserExampleValues _exampleValues;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
|
||||||
|
namespace WireMock.Net.OpenApiParser.Utils;
|
||||||
|
|
||||||
|
internal interface IExampleValueGenerator
|
||||||
|
{
|
||||||
|
object GetExampleValue(OpenApiSchema? schema);
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Stef.Validation;
|
||||||
|
using WireMock.Net.OpenApiParser.Extensions;
|
||||||
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
|
using WireMock.Net.OpenApiParser.Types;
|
||||||
|
|
||||||
|
namespace WireMock.Net.OpenApiParser.Utils;
|
||||||
|
|
||||||
|
internal class RegexExampleValueGenerator : IExampleValueGenerator
|
||||||
|
{
|
||||||
|
public RegexExampleValueGenerator(WireMockOpenApiParserSettings settings)
|
||||||
|
{
|
||||||
|
Guard.NotNull(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public object GetExampleValue(OpenApiSchema? schema)
|
||||||
|
{
|
||||||
|
switch (schema?.GetSchemaType())
|
||||||
|
{
|
||||||
|
case SchemaType.Boolean:
|
||||||
|
return @"(true|false)";
|
||||||
|
|
||||||
|
case SchemaType.Integer:
|
||||||
|
return @"-?\d+";
|
||||||
|
|
||||||
|
case SchemaType.Number:
|
||||||
|
return @"[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return schema?.GetSchemaFormat() switch
|
||||||
|
{
|
||||||
|
SchemaFormat.Date => @"(\d{4})-([01]\d)-([0-3]\d)",
|
||||||
|
SchemaFormat.DateTime => @"(\d{4})-([01]\d)-([0-3]\d)T([0-2]\d):([0-5]\d):([0-5]\d)(\.\d+)?(Z|[+-][0-2]\d:[0-5]\d)",
|
||||||
|
SchemaFormat.Byte => @"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
|
||||||
|
SchemaFormat.Binary => @"[a-zA-Z0-9\+/]*={0,3}",
|
||||||
|
_ => ".*"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ using RamlToOpenApiConverter;
|
|||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Net.OpenApiParser.Mappers;
|
using WireMock.Net.OpenApiParser.Mappers;
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
|
using WireMock.Net.OpenApiParser.Types;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser;
|
namespace WireMock.Net.OpenApiParser;
|
||||||
|
|
||||||
@@ -17,13 +18,20 @@ namespace WireMock.Net.OpenApiParser;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||||
{
|
{
|
||||||
|
private readonly WireMockOpenApiParserSettings _wireMockOpenApiParserSettings = new WireMockOpenApiParserSettings
|
||||||
|
{
|
||||||
|
HeaderPatternToUse = ExampleValueType.Regex,
|
||||||
|
QueryParameterPatternToUse = ExampleValueType.Regex,
|
||||||
|
PathPatternToUse = ExampleValueType.Regex
|
||||||
|
};
|
||||||
|
|
||||||
private readonly OpenApiStreamReader _reader = new();
|
private readonly OpenApiStreamReader _reader = new();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IReadOnlyList<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic)
|
public IReadOnlyList<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic)
|
||||||
{
|
{
|
||||||
return FromFile(path, new WireMockOpenApiParserSettings(), out diagnostic);
|
return FromFile(path, _wireMockOpenApiParserSettings, out diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -47,9 +55,9 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public IReadOnlyList<MappingModel> FromDocument(OpenApiDocument document, WireMockOpenApiParserSettings? settings = null)
|
public IReadOnlyList<MappingModel> FromDocument(OpenApiDocument openApiDocument, WireMockOpenApiParserSettings? settings = null)
|
||||||
{
|
{
|
||||||
return new OpenApiPathsMapper(settings ?? new WireMockOpenApiParserSettings()).ToMappingModels(document.Paths, document.Servers);
|
return new OpenApiPathsMapper(settings ?? _wireMockOpenApiParserSettings).ToMappingModels(openApiDocument.Paths, openApiDocument.Servers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@@ -25,7 +24,7 @@ public static class StandAloneApp
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static WireMockServer Start(WireMockServerSettings settings)
|
public static WireMockServer Start(WireMockServerSettings settings)
|
||||||
{
|
{
|
||||||
Guard.NotNull(settings);
|
Guard.NotNull(settings, nameof(settings));
|
||||||
|
|
||||||
var server = WireMockServer.Start(settings);
|
var server = WireMockServer.Start(settings);
|
||||||
|
|
||||||
@@ -43,7 +42,7 @@ public static class StandAloneApp
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static WireMockServer Start(string[] args, IWireMockLogger? logger = null)
|
public static WireMockServer Start(string[] args, IWireMockLogger? logger = null)
|
||||||
{
|
{
|
||||||
Guard.NotNull(args);
|
Guard.NotNull(args, nameof(args));
|
||||||
|
|
||||||
if (TryStart(args, out var server, logger))
|
if (TryStart(args, out var server, logger))
|
||||||
{
|
{
|
||||||
@@ -62,9 +61,9 @@ public static class StandAloneApp
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static bool TryStart(string[] args, [NotNullWhen(true)] out WireMockServer? server, IWireMockLogger? logger = null)
|
public static bool TryStart(string[] args, [NotNullWhen(true)] out WireMockServer? server, IWireMockLogger? logger = null)
|
||||||
{
|
{
|
||||||
Guard.NotNull(args);
|
Guard.NotNull(args, nameof(args));
|
||||||
|
|
||||||
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, logger))
|
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings, logger))
|
||||||
{
|
{
|
||||||
settings.Logger?.Info("Version [{0}]", Version);
|
settings.Logger?.Info("Version [{0}]", Version);
|
||||||
settings.Logger?.Debug("Server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
settings.Logger?.Debug("Server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace WireMock.Net.Testcontainers.Models;
|
|
||||||
|
|
||||||
internal record ContainerInfo
|
|
||||||
(
|
|
||||||
string Image,
|
|
||||||
string MappingsPath
|
|
||||||
);
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<Description>A fluent testcontainer builder for the Docker version of WireMock.Net</Description>
|
|
||||||
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
|
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
||||||
<PackageTags>wiremock;docker;testcontainer;testcontainers</PackageTags>
|
|
||||||
<ProjectGuid>{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}</ProjectGuid>
|
|
||||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
|
||||||
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
|
||||||
<SignAssembly>true</SignAssembly>
|
|
||||||
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
|
||||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
|
||||||
<LangVersion>10</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="IsExternalInit" Version="1.0.3">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
|
|
||||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
|
||||||
<PackageReference Include="Testcontainers" Version="3.2.0" />
|
|
||||||
<PackageReference Include="JetBrains.Annotations" VersionOverride="2022.3.1" PrivateAssets="All" Version="2022.3.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
using Docker.DotNet.Models;
|
|
||||||
using DotNet.Testcontainers.Builders;
|
|
||||||
using DotNet.Testcontainers.Configurations;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Testcontainers;
|
|
||||||
|
|
||||||
/// <inheritdoc cref="ContainerConfiguration" />
|
|
||||||
[PublicAPI]
|
|
||||||
public sealed class WireMockConfiguration : ContainerConfiguration
|
|
||||||
{
|
|
||||||
#pragma warning disable CS1591
|
|
||||||
public string? Username { get; }
|
|
||||||
|
|
||||||
public string? Password { get; }
|
|
||||||
|
|
||||||
public bool HasBasicAuthentication => !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
|
|
||||||
|
|
||||||
public WireMockConfiguration(
|
|
||||||
string? username = null,
|
|
||||||
string? password = null
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Username = username;
|
|
||||||
Password = password;
|
|
||||||
}
|
|
||||||
#pragma warning restore CS1591
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
|
|
||||||
public WireMockConfiguration(IResourceConfiguration<CreateContainerParameters> resourceConfiguration) : base(resourceConfiguration)
|
|
||||||
{
|
|
||||||
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
|
|
||||||
public WireMockConfiguration(IContainerConfiguration resourceConfiguration) : base(resourceConfiguration)
|
|
||||||
{
|
|
||||||
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="resourceConfiguration">The Docker resource configuration.</param>
|
|
||||||
public WireMockConfiguration(WireMockConfiguration resourceConfiguration) : this(new WireMockConfiguration(), resourceConfiguration)
|
|
||||||
{
|
|
||||||
// Passes the configuration upwards to the base implementations to create an updated immutable copy.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WireMockConfiguration" /> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="oldValue">The old Docker resource configuration.</param>
|
|
||||||
/// <param name="newValue">The new Docker resource configuration.</param>
|
|
||||||
public WireMockConfiguration(WireMockConfiguration oldValue, WireMockConfiguration newValue) : base(oldValue, newValue)
|
|
||||||
{
|
|
||||||
Username = BuildConfiguration.Combine(oldValue.Username, newValue.Username);
|
|
||||||
Password = BuildConfiguration.Combine(oldValue.Password, newValue.Password);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Text;
|
|
||||||
using DotNet.Testcontainers.Containers;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using RestEase;
|
|
||||||
using Stef.Validation;
|
|
||||||
using WireMock.Client;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Testcontainers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A container for running WireMock in a docker environment.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class WireMockContainer : DockerContainer
|
|
||||||
{
|
|
||||||
internal const int ContainerPort = 80;
|
|
||||||
|
|
||||||
private readonly WireMockConfiguration _configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WireMockContainer" /> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="configuration">The container configuration.</param>
|
|
||||||
/// <param name="logger">The logger.</param>
|
|
||||||
public WireMockContainer(WireMockConfiguration configuration, ILogger logger) : base(configuration, logger)
|
|
||||||
{
|
|
||||||
_configuration = Guard.NotNull(configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the public Url.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
|
||||||
public string GetPublicUrl() => GetPublicUri().ToString();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a RestEase Admin client which can be used to call the admin REST endpoint.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A <see cref="IWireMockAdminApi"/></returns>
|
|
||||||
[PublicAPI]
|
|
||||||
public IWireMockAdminApi CreateWireMockAdminClient()
|
|
||||||
{
|
|
||||||
ValidateIfRunning();
|
|
||||||
|
|
||||||
var api = RestClient.For<IWireMockAdminApi>(GetPublicUri());
|
|
||||||
|
|
||||||
if (_configuration.HasBasicAuthentication)
|
|
||||||
{
|
|
||||||
api.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{_configuration.Username}:{_configuration.Password}")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return api;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="HttpClient"/> which can be used to call this instance.
|
|
||||||
/// <param name="handlers">
|
|
||||||
/// An ordered list of System.Net.Http.DelegatingHandler instances to be invoked
|
|
||||||
/// as an System.Net.Http.HttpRequestMessage travels from the System.Net.Http.HttpClient
|
|
||||||
/// to the network and an System.Net.Http.HttpResponseMessage travels from the network
|
|
||||||
/// back to System.Net.Http.HttpClient. The handlers are invoked in a top-down fashion.
|
|
||||||
/// That is, the first entry is invoked first for an outbound request message but
|
|
||||||
/// last for an inbound response message.
|
|
||||||
/// </param>
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
|
||||||
public HttpClient CreateClient(params DelegatingHandler[] handlers)
|
|
||||||
{
|
|
||||||
ValidateIfRunning();
|
|
||||||
|
|
||||||
var client = HttpClientFactory.Create(handlers);
|
|
||||||
client.BaseAddress = GetPublicUri();
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a <see cref="HttpClient"/> (one for each URL) which can be used to call this instance.
|
|
||||||
/// <param name="innerHandler">The inner handler represents the destination of the HTTP message channel.</param>
|
|
||||||
/// <param name="handlers">
|
|
||||||
/// An ordered list of System.Net.Http.DelegatingHandler instances to be invoked
|
|
||||||
/// as an System.Net.Http.HttpRequestMessage travels from the System.Net.Http.HttpClient
|
|
||||||
/// to the network and an System.Net.Http.HttpResponseMessage travels from the network
|
|
||||||
/// back to System.Net.Http.HttpClient. The handlers are invoked in a top-down fashion.
|
|
||||||
/// That is, the first entry is invoked first for an outbound request message but
|
|
||||||
/// last for an inbound response message.
|
|
||||||
/// </param>
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
|
||||||
public HttpClient CreateClient(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers)
|
|
||||||
{
|
|
||||||
ValidateIfRunning();
|
|
||||||
|
|
||||||
var client = HttpClientFactory.Create(innerHandler, handlers);
|
|
||||||
client.BaseAddress = GetPublicUri();
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ValidateIfRunning()
|
|
||||||
{
|
|
||||||
if (State != TestcontainersStates.Running)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Unable to create HttpClient because the WireMock.Net is not yet running.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Uri GetPublicUri() => new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(ContainerPort)).Uri;
|
|
||||||
}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Docker.DotNet.Models;
|
|
||||||
using DotNet.Testcontainers.Builders;
|
|
||||||
using DotNet.Testcontainers.Configurations;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Stef.Validation;
|
|
||||||
using WireMock.Net.Testcontainers.Models;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Testcontainers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An specific fluent Docker container builder for WireMock.Net
|
|
||||||
/// </summary>
|
|
||||||
public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContainerBuilder, WireMockContainer, WireMockConfiguration>
|
|
||||||
{
|
|
||||||
private readonly Dictionary<bool, ContainerInfo> _info = new()
|
|
||||||
{
|
|
||||||
{ false, new ContainerInfo("sheyenrath/wiremock.net:latest", "/app/__admin/mappings") },
|
|
||||||
{ true, new ContainerInfo("sheyenrath/wiremock.net-windows:latest", @"c:\app\__admin\mappings") }
|
|
||||||
};
|
|
||||||
|
|
||||||
private const string DefaultLogger = "WireMockConsoleLogger";
|
|
||||||
|
|
||||||
private readonly Lazy<Task<bool>> _isWindowsAsLazy = new(async () =>
|
|
||||||
{
|
|
||||||
using var dockerClientConfig = TestcontainersSettings.OS.DockerEndpointAuthConfig.GetDockerClientConfiguration();
|
|
||||||
using var dockerClient = dockerClientConfig.CreateClient();
|
|
||||||
|
|
||||||
var version = await dockerClient.System.GetVersionAsync();
|
|
||||||
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
|
|
||||||
/// </summary>
|
|
||||||
public WireMockContainerBuilder() : this(new WireMockConfiguration())
|
|
||||||
{
|
|
||||||
DockerResourceConfiguration = Init().DockerResourceConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Automatically set the correct image (Linux or Windows) for WireMock which to create the container.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
|
|
||||||
[PublicAPI]
|
|
||||||
public WireMockContainerBuilder WithImage()
|
|
||||||
{
|
|
||||||
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
|
|
||||||
return WithImage(_info[isWindows].Image);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the admin username and password for the container (basic authentication).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="username">The admin username.</param>
|
|
||||||
/// <param name="password">The admin password.</param>
|
|
||||||
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
|
|
||||||
public WireMockContainerBuilder WithAdminUserNameAndPassword(string username, string password)
|
|
||||||
{
|
|
||||||
Guard.NotNull(username);
|
|
||||||
Guard.NotNull(password);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(username) && string.IsNullOrEmpty(password))
|
|
||||||
{
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Merge(DockerResourceConfiguration, new WireMockConfiguration(username, password))
|
|
||||||
.WithCommand($"--AdminUserName {username}", $"--AdminPassword {password}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Use the WireMockNullLogger.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
|
|
||||||
[PublicAPI]
|
|
||||||
public WireMockContainerBuilder WithNullLogger()
|
|
||||||
{
|
|
||||||
return WithCommand("--WireMockLogger WireMockNullLogger");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines if the static mappings should be read at startup (default set to false).
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
|
|
||||||
[PublicAPI]
|
|
||||||
public WireMockContainerBuilder WithReadStaticMappings()
|
|
||||||
{
|
|
||||||
return WithCommand("--ReadStaticMappings true");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Watch the static mapping files + folder for changes when running.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
|
|
||||||
[PublicAPI]
|
|
||||||
public WireMockContainerBuilder WithWatchStaticMappings(bool includeSubDirectories)
|
|
||||||
{
|
|
||||||
return WithCommand("--WatchStaticMappings true").WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies the path for the (static) mapping json files.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="path">The path</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[PublicAPI]
|
|
||||||
public WireMockContainerBuilder WithMappings(string path)
|
|
||||||
{
|
|
||||||
Guard.NotNullOrEmpty(path);
|
|
||||||
|
|
||||||
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
return WithReadStaticMappings().WithBindMount(path, _info[isWindows].MappingsPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="WireMockContainerBuilder" /> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dockerResourceConfiguration">The Docker resource configuration.</param>
|
|
||||||
private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration)
|
|
||||||
{
|
|
||||||
DockerResourceConfiguration = dockerResourceConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override WireMockConfiguration DockerResourceConfiguration { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public override WireMockContainer Build()
|
|
||||||
{
|
|
||||||
Validate();
|
|
||||||
|
|
||||||
return new WireMockContainer(DockerResourceConfiguration, TestcontainersSettings.Logger);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override WireMockContainerBuilder Init()
|
|
||||||
{
|
|
||||||
var builder = base.Init();
|
|
||||||
|
|
||||||
// In case no image has been set, set the image using internal logic.
|
|
||||||
if (builder.DockerResourceConfiguration.Image == null)
|
|
||||||
{
|
|
||||||
builder = builder.WithImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
|
|
||||||
var waitForContainerOS = isWindows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
|
|
||||||
return builder
|
|
||||||
.WithPortBinding(WireMockContainer.ContainerPort, true)
|
|
||||||
.WithCommand($"--WireMockLogger {DefaultLogger}")
|
|
||||||
.WithWaitStrategy(waitForContainerOS.UntilMessageIsLogged("By Stef Heyenrath"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override WireMockContainerBuilder Clone(IContainerConfiguration resourceConfiguration)
|
|
||||||
{
|
|
||||||
return Merge(DockerResourceConfiguration, new WireMockConfiguration(resourceConfiguration));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override WireMockContainerBuilder Clone(IResourceConfiguration<CreateContainerParameters> resourceConfiguration)
|
|
||||||
{
|
|
||||||
return Merge(DockerResourceConfiguration, new WireMockConfiguration(resourceConfiguration));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override WireMockContainerBuilder Merge(WireMockConfiguration oldValue, WireMockConfiguration newValue)
|
|
||||||
{
|
|
||||||
return new WireMockContainerBuilder(new WireMockConfiguration(oldValue, newValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Stef.Validation;
|
|
||||||
|
|
||||||
namespace WireMock.Extensions;
|
|
||||||
|
|
||||||
internal static class DictionaryExtensions
|
|
||||||
{
|
|
||||||
public static bool TryGetStringValue(this IDictionary dictionary, string key, [NotNullWhen(true)] out string? value)
|
|
||||||
{
|
|
||||||
Guard.NotNull(dictionary);
|
|
||||||
|
|
||||||
if (dictionary[key] is string valueIsString)
|
|
||||||
{
|
|
||||||
value = valueIsString;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var valueToString = dictionary[key]?.ToString();
|
|
||||||
if (valueToString != null)
|
|
||||||
{
|
|
||||||
value = valueToString;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = default;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,18 +5,12 @@ using System.Net.Http;
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.Constants;
|
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
|
|
||||||
namespace WireMock.Http;
|
namespace WireMock.Http;
|
||||||
|
|
||||||
internal static class HttpRequestMessageHelper
|
internal static class HttpRequestMessageHelper
|
||||||
{
|
{
|
||||||
private static readonly IDictionary<string, bool> ContentLengthHeaderAllowed = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
{ HttpRequestMethod.HEAD, true }
|
|
||||||
};
|
|
||||||
|
|
||||||
internal static HttpRequestMessage Create(IRequestMessage requestMessage, string url)
|
internal static HttpRequestMessage Create(IRequestMessage requestMessage, string url)
|
||||||
{
|
{
|
||||||
Guard.NotNull(requestMessage);
|
Guard.NotNull(requestMessage);
|
||||||
@@ -56,19 +50,7 @@ internal static class HttpRequestMessageHelper
|
|||||||
return httpRequestMessage;
|
return httpRequestMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host };
|
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };
|
||||||
|
|
||||||
var contentLengthHeaderAllowed = ContentLengthHeaderAllowed.TryGetValue(requestMessage.Method, out var allowed) && allowed;
|
|
||||||
if (contentLengthHeaderAllowed)
|
|
||||||
{
|
|
||||||
// Set Content to empty ByteArray to be able to set the Content-Length on the content in case of a HEAD method.
|
|
||||||
httpRequestMessage.Content ??= new ByteArrayContent(EmptyArray<byte>.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
excludeHeaders.Add(HttpKnownHeaderNames.ContentLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentType != null)
|
if (contentType != null)
|
||||||
{
|
{
|
||||||
// Content-Type should be set on the content
|
// Content-Type should be set on the content
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
#if GRAPHQL
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using AnyOfTypes;
|
|
||||||
using GraphQL;
|
|
||||||
using GraphQL.Types;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
using Stef.Validation;
|
|
||||||
using WireMock.Models;
|
|
||||||
|
|
||||||
namespace WireMock.Matchers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// GrapQLMatcher Schema Matcher
|
|
||||||
/// </summary>
|
|
||||||
/// <inheritdoc cref="IStringMatcher"/>
|
|
||||||
public class GraphQLMatcher : IStringMatcher
|
|
||||||
{
|
|
||||||
private sealed class GraphQLRequest
|
|
||||||
{
|
|
||||||
public string? Query { get; set; }
|
|
||||||
|
|
||||||
public Dictionary<string, object?>? Variables { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
|
||||||
|
|
||||||
private readonly ISchema _schema;
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public MatchBehaviour MatchBehaviour { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public bool ThrowException { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="schema">The schema.</param>
|
|
||||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
|
||||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
|
||||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
|
||||||
public GraphQLMatcher(AnyOf<string, StringPattern, ISchema> schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, bool throwException = false, MatchOperator matchOperator = MatchOperator.Or)
|
|
||||||
{
|
|
||||||
Guard.NotNull(schema);
|
|
||||||
MatchBehaviour = matchBehaviour;
|
|
||||||
ThrowException = throwException;
|
|
||||||
MatchOperator = matchOperator;
|
|
||||||
|
|
||||||
var patterns = new List<AnyOf<string, StringPattern>>();
|
|
||||||
switch (schema.CurrentType)
|
|
||||||
{
|
|
||||||
case AnyOfType.First:
|
|
||||||
patterns.Add(schema.First);
|
|
||||||
_schema = BuildSchema(schema);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AnyOfType.Second:
|
|
||||||
patterns.Add(schema.Second);
|
|
||||||
_schema = BuildSchema(schema.Second.Pattern);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AnyOfType.Third:
|
|
||||||
_schema = schema.Third;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
_patterns = patterns.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public double IsMatch(string? input)
|
|
||||||
{
|
|
||||||
var match = MatchScores.Mismatch;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var graphQLRequest = JsonConvert.DeserializeObject<GraphQLRequest>(input!)!;
|
|
||||||
|
|
||||||
var executionResult = new DocumentExecuter().ExecuteAsync(_ =>
|
|
||||||
{
|
|
||||||
_.ThrowOnUnhandledException = true;
|
|
||||||
|
|
||||||
_.Schema = _schema;
|
|
||||||
_.Query = graphQLRequest.Query;
|
|
||||||
|
|
||||||
if (graphQLRequest.Variables != null)
|
|
||||||
{
|
|
||||||
_.Variables = new Inputs(graphQLRequest.Variables);
|
|
||||||
}
|
|
||||||
}).GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
if (executionResult.Errors == null || executionResult.Errors.Count == 0)
|
|
||||||
{
|
|
||||||
match = MatchScores.Perfect;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var exceptions = executionResult.Errors.OfType<Exception>().ToArray();
|
|
||||||
if (exceptions.Length == 1)
|
|
||||||
{
|
|
||||||
throw exceptions[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new AggregateException(exceptions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
if (ThrowException)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
|
||||||
{
|
|
||||||
return _patterns;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public MatchOperator MatchOperator { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc cref="IMatcher.Name"/>
|
|
||||||
public string Name => nameof(GraphQLMatcher);
|
|
||||||
|
|
||||||
private static ISchema BuildSchema(string schema)
|
|
||||||
{
|
|
||||||
return Schema.For(schema);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -121,32 +121,6 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
|||||||
|
|
||||||
private double IsMatch(JToken jToken)
|
private double IsMatch(JToken jToken)
|
||||||
{
|
{
|
||||||
var array = ConvertJTokenToJArrayIfNeeded(jToken);
|
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
|
||||||
|
|
||||||
return MatchScores.ToScore(_patterns.Select(pattern => array.SelectToken(pattern.GetPattern())?.Any() == true).ToArray(), MatchOperator);
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://github.com/WireMock-Net/WireMock.Net/issues/965
|
|
||||||
// https://stackoverflow.com/questions/66922188/newtonsoft-jsonpath-with-c-sharp-syntax
|
|
||||||
// Filtering using SelectToken() isn't guaranteed to work for objects inside objects -- only objects inside arrays.
|
|
||||||
// So this code checks if it's an JArray, if it's not an array, construct a new JArray.
|
|
||||||
private static JToken ConvertJTokenToJArrayIfNeeded(JToken jToken)
|
|
||||||
{
|
|
||||||
if (jToken.Count() == 1)
|
|
||||||
{
|
|
||||||
var property = jToken.First();
|
|
||||||
var item = property.First();
|
|
||||||
if (item is JArray)
|
|
||||||
{
|
|
||||||
return jToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new JObject
|
|
||||||
{
|
|
||||||
[property.Path] = new JArray(item)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return jToken;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
|||||||
MatchOperator = matchOperator;
|
MatchOperator = matchOperator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||||
public double IsMatch(string? input)
|
public double IsMatch(string? input)
|
||||||
{
|
{
|
||||||
double match = MatchScores.Mismatch;
|
double match = MatchScores.Mismatch;
|
||||||
@@ -95,7 +95,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
|||||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||||
public double IsMatch(object? input)
|
public double IsMatch(object? input)
|
||||||
{
|
{
|
||||||
double match = MatchScores.Mismatch;
|
double match = MatchScores.Mismatch;
|
||||||
@@ -110,15 +110,41 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
|||||||
jArray = new JArray { JToken.FromObject(input) };
|
jArray = new JArray { JToken.FromObject(input) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//enumerable = jArray.ToDynamicClassArray();
|
||||||
|
|
||||||
|
//JObject value;
|
||||||
|
//switch (input)
|
||||||
|
//{
|
||||||
|
// case JObject valueAsJObject:
|
||||||
|
// value = valueAsJObject;
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case { } valueAsObject:
|
||||||
|
// value = JObject.FromObject(valueAsObject);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// default:
|
||||||
|
// return MatchScores.Mismatch;
|
||||||
|
//}
|
||||||
|
|
||||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||||
|
//var queryable1 = new[] { value }.AsQueryable();
|
||||||
var queryable = jArray.ToDynamicClassArray().AsQueryable();
|
var queryable = jArray.ToDynamicClassArray().AsQueryable();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Generate the DynamicLinq select statement.
|
||||||
|
//string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value);
|
||||||
|
|
||||||
|
// Execute DynamicLinq Select statement.
|
||||||
|
//var queryable2 = queryable1.Select(dynamicSelect);
|
||||||
|
|
||||||
|
// Use the Any(...) method to check if the result matches.
|
||||||
|
|
||||||
var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray();
|
var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray();
|
||||||
var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray();
|
var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray();
|
||||||
|
|
||||||
match = MatchScores.ToScore(scores, MatchOperator);
|
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
|
||||||
|
|
||||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||||
}
|
}
|
||||||
@@ -133,7 +159,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
|||||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||||
{
|
{
|
||||||
return _patterns;
|
return _patterns;
|
||||||
@@ -142,6 +168,6 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public MatchOperator MatchOperator { get; }
|
public MatchOperator MatchOperator { get; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc cref="IMatcher.Name"/>
|
||||||
public string Name => "LinqMatcher";
|
public string Name => "LinqMatcher";
|
||||||
}
|
}
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using Stef.Validation;
|
|
||||||
using WireMock.Types;
|
|
||||||
|
|
||||||
namespace WireMock.Matchers.Request;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The request body GraphQL matcher.
|
|
||||||
/// </summary>
|
|
||||||
public class RequestMessageGraphQLMatcher : IRequestMatcher
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The matchers.
|
|
||||||
/// </summary>
|
|
||||||
public IMatcher[]? Matchers { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The <see cref="MatchOperator"/>
|
|
||||||
/// </summary>
|
|
||||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
|
||||||
/// <param name="schema">The schema.</param>
|
|
||||||
public RequestMessageGraphQLMatcher(MatchBehaviour matchBehaviour, string schema) :
|
|
||||||
this(CreateMatcherArray(matchBehaviour, schema))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GRAPHQL
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
|
||||||
/// <param name="schema">The schema.</param>
|
|
||||||
public RequestMessageGraphQLMatcher(MatchBehaviour matchBehaviour, GraphQL.Types.ISchema schema) :
|
|
||||||
this(CreateMatcherArray(matchBehaviour, new AnyOfTypes.AnyOf<string, Models.StringPattern, GraphQL.Types.ISchema>(schema)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="matchers">The matchers.</param>
|
|
||||||
public RequestMessageGraphQLMatcher(params IMatcher[] matchers)
|
|
||||||
{
|
|
||||||
Matchers = Guard.NotNull(matchers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="matchers">The matchers.</param>
|
|
||||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
|
||||||
public RequestMessageGraphQLMatcher(MatchOperator matchOperator, params IMatcher[] matchers)
|
|
||||||
{
|
|
||||||
Matchers = Guard.NotNull(matchers);
|
|
||||||
MatchOperator = matchOperator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
|
||||||
{
|
|
||||||
var score = CalculateMatchScore(requestMessage);
|
|
||||||
return requestMatchResult.AddScore(GetType(), score);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
|
||||||
{
|
|
||||||
// Check if the matcher is a IStringMatcher
|
|
||||||
// If the body is a Json or a String, use the BodyAsString to match on.
|
|
||||||
if (matcher is IStringMatcher stringMatcher && requestMessage.BodyData?.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
|
|
||||||
{
|
|
||||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
return MatchScores.Mismatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
|
||||||
{
|
|
||||||
if (Matchers == null)
|
|
||||||
{
|
|
||||||
return MatchScores.Mismatch;
|
|
||||||
}
|
|
||||||
|
|
||||||
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
|
|
||||||
return MatchScores.ToScore(matchersResult, MatchOperator);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GRAPHQL
|
|
||||||
private static IMatcher[] CreateMatcherArray(MatchBehaviour matchBehaviour, AnyOfTypes.AnyOf<string, Models.StringPattern, GraphQL.Types.ISchema> schema)
|
|
||||||
{
|
|
||||||
return new[] { new GraphQLMatcher(schema, matchBehaviour) }.Cast<IMatcher>().ToArray();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
private static IMatcher[] CreateMatcherArray(MatchBehaviour matchBehaviour, object schema)
|
|
||||||
{
|
|
||||||
throw new System.NotSupportedException("The GrapQLMatcher can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ namespace WireMock.RequestBuilders;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The BodyRequestBuilder interface.
|
/// The BodyRequestBuilder interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBodyRequestBuilder : IGraphQLRequestBuilder
|
public interface IBodyRequestBuilder : IRequestMatcher
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithBody: IMatcher
|
/// WithBody: IMatcher
|
||||||
@@ -103,12 +103,4 @@ public interface IBodyRequestBuilder : IGraphQLRequestBuilder
|
|||||||
/// <param name="func">The form-urlencoded values.</param>
|
/// <param name="func">The form-urlencoded values.</param>
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
IRequestBuilder WithBody(Func<IDictionary<string, string>?, bool> func);
|
IRequestBuilder WithBody(Func<IDictionary<string, string>?, bool> func);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// WithBodyAsGraphQLSchema: Body as GraphQL schema as a string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="body">The GraphQL schema.</param>
|
|
||||||
/// <param name="matchBehaviour">The match behaviour. (Default is <c>MatchBehaviour.AcceptOnMatch</c>).</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
IRequestBuilder WithBodyAsGraphQLSchema(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
|
||||||
}
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using WireMock.Matchers;
|
|
||||||
using WireMock.Matchers.Request;
|
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The GraphQLRequestBuilder interface.
|
|
||||||
/// </summary>
|
|
||||||
public interface IGraphQLRequestBuilder : IRequestMatcher
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// WithGraphQLSchema: The GraphQL schema as a string.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="schema">The GraphQL schema.</param>
|
|
||||||
/// <param name="matchBehaviour">The match behaviour. (Default is <c>MatchBehaviour.AcceptOnMatch</c>).</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
IRequestBuilder WithGraphQLSchema(string schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
|
||||||
|
|
||||||
#if GRAPHQL
|
|
||||||
/// <summary>
|
|
||||||
/// WithGraphQLSchema: The GraphQL schema as a ISchema.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="schema">The GraphQL schema.</param>
|
|
||||||
/// <param name="matchBehaviour">The match behaviour. (Default is <c>MatchBehaviour.AcceptOnMatch</c>).</param>
|
|
||||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
|
||||||
IRequestBuilder WithGraphQLSchema(GraphQL.Types.ISchema schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -109,10 +109,4 @@ public partial class Request
|
|||||||
_requestMatchers.Add(new RequestMessageBodyMatcher(Guard.NotNull(func)));
|
_requestMatchers.Add(new RequestMessageBodyMatcher(Guard.NotNull(func)));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IRequestBuilder WithBodyAsGraphQLSchema(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
|
||||||
{
|
|
||||||
return WithGraphQLSchema(body, matchBehaviour);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using WireMock.Matchers;
|
|
||||||
using WireMock.Matchers.Request;
|
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders;
|
|
||||||
|
|
||||||
public partial class Request
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IRequestBuilder WithGraphQLSchema(string schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
|
||||||
{
|
|
||||||
_requestMatchers.Add(new RequestMessageGraphQLMatcher(matchBehaviour, schema));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GRAPHQL
|
|
||||||
/// <inheritdoc />
|
|
||||||
public IRequestBuilder WithGraphQLSchema(GraphQL.Types.ISchema schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
|
||||||
{
|
|
||||||
_requestMatchers.Add(new RequestMessageGraphQLMatcher(matchBehaviour, schema));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -46,8 +46,7 @@ internal class MappingConverter
|
|||||||
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
|
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
|
||||||
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
||||||
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
||||||
var requestMessageBodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||||
var requestMessageGraphQLMatcher = request.GetRequestMessageMatcher<RequestMessageGraphQLMatcher>();
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
@@ -106,23 +105,13 @@ internal class MappingConverter
|
|||||||
sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)");
|
sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GRAPHQL
|
if (bodyMatcher is { Matchers: { } })
|
||||||
if (requestMessageGraphQLMatcher is { Matchers: { } })
|
|
||||||
{
|
{
|
||||||
if (requestMessageGraphQLMatcher.Matchers.OfType<GraphQLMatcher>().FirstOrDefault() is { } graphQLMatcher && graphQLMatcher.GetPatterns().Any())
|
if (bodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
|
||||||
{
|
|
||||||
sb.AppendLine($" .WithGraphQLSchema({GetString(graphQLMatcher)})");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (requestMessageBodyMatcher is { Matchers: { } })
|
|
||||||
{
|
|
||||||
if (requestMessageBodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
|
|
||||||
{
|
{
|
||||||
sb.AppendLine($" .WithBody({GetString(wildcardMatcher)})");
|
sb.AppendLine($" .WithBody({GetString(wildcardMatcher)})");
|
||||||
}
|
}
|
||||||
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
|
else if (bodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
|
||||||
{
|
{
|
||||||
sb.AppendLine(@$" .WithBody(new JsonPartialMatcher(
|
sb.AppendLine(@$" .WithBody(new JsonPartialMatcher(
|
||||||
value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())},
|
value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())},
|
||||||
@@ -131,7 +120,7 @@ internal class MappingConverter
|
|||||||
regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)}
|
regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)}
|
||||||
))");
|
))");
|
||||||
}
|
}
|
||||||
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)
|
else if (bodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)
|
||||||
{
|
{
|
||||||
sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher(
|
sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher(
|
||||||
value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())},
|
value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())},
|
||||||
@@ -227,7 +216,6 @@ internal class MappingConverter
|
|||||||
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
||||||
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
||||||
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||||
var graphQLMatcher = request.GetRequestMessageMatcher<RequestMessageGraphQLMatcher>();
|
|
||||||
|
|
||||||
var mappingModel = new MappingModel
|
var mappingModel = new MappingModel
|
||||||
{
|
{
|
||||||
@@ -313,7 +301,7 @@ internal class MappingConverter
|
|||||||
mappingModel.Response.Delay = (int?)(response.Delay == Timeout.InfiniteTimeSpan ? TimeSpan.MaxValue.TotalMilliseconds : response.Delay?.TotalMilliseconds);
|
mappingModel.Response.Delay = (int?)(response.Delay == Timeout.InfiniteTimeSpan ? TimeSpan.MaxValue.TotalMilliseconds : response.Delay?.TotalMilliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
var nonNullableWebHooks = mapping.Webhooks?.Where(wh => wh != null).ToArray() ?? EmptyArray<IWebhook>.Value;
|
var nonNullableWebHooks = mapping.Webhooks?.Where(wh => wh != null).ToArray() ?? new IWebhook[0];
|
||||||
if (nonNullableWebHooks.Length == 1)
|
if (nonNullableWebHooks.Length == 1)
|
||||||
{
|
{
|
||||||
mappingModel.Webhook = WebhookMapper.Map(nonNullableWebHooks[0]);
|
mappingModel.Webhook = WebhookMapper.Map(nonNullableWebHooks[0]);
|
||||||
@@ -323,20 +311,18 @@ internal class MappingConverter
|
|||||||
mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
|
mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
var graphQLOrBodyMatchers = graphQLMatcher?.Matchers ?? bodyMatcher?.Matchers;
|
if (bodyMatcher?.Matchers != null)
|
||||||
var matchOperator = graphQLMatcher?.MatchOperator ?? bodyMatcher?.MatchOperator;
|
|
||||||
if (graphQLOrBodyMatchers != null && matchOperator != null)
|
|
||||||
{
|
{
|
||||||
mappingModel.Request.Body = new BodyModel();
|
mappingModel.Request.Body = new BodyModel();
|
||||||
|
|
||||||
if (graphQLOrBodyMatchers.Length == 1)
|
if (bodyMatcher.Matchers.Length == 1)
|
||||||
{
|
{
|
||||||
mappingModel.Request.Body.Matcher = _mapper.Map(graphQLOrBodyMatchers[0]);
|
mappingModel.Request.Body.Matcher = _mapper.Map(bodyMatcher.Matchers[0]);
|
||||||
}
|
}
|
||||||
else if (graphQLOrBodyMatchers.Length > 1)
|
else if (bodyMatcher.Matchers.Length > 1)
|
||||||
{
|
{
|
||||||
mappingModel.Request.Body.Matchers = _mapper.Map(graphQLOrBodyMatchers);
|
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatcher.Matchers);
|
||||||
mappingModel.Request.Body.MatchOperator = matchOperator.ToString();
|
mappingModel.Request.Body.MatchOperator = bodyMatcher.MatchOperator.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,10 +71,7 @@ internal class MatcherMapper
|
|||||||
|
|
||||||
case nameof(ExactObjectMatcher):
|
case nameof(ExactObjectMatcher):
|
||||||
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
|
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
|
||||||
#if GRAPHQL
|
|
||||||
case nameof(GraphQLMatcher):
|
|
||||||
return new GraphQLMatcher(stringPatterns[0].GetPattern(), matchBehaviour, throwExceptionWhenMatcherFails, matchOperator);
|
|
||||||
#endif
|
|
||||||
case nameof(RegexMatcher):
|
case nameof(RegexMatcher):
|
||||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended, matchOperator);
|
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended, matchOperator);
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,39 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using WireMock.Net.OpenApiParser;
|
using WireMock.Net.OpenApiParser;
|
||||||
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
|
using WireMock.Net.OpenApiParser.Types;
|
||||||
|
using WireMock.Serialization;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace WireMock.Server;
|
namespace WireMock.Server;
|
||||||
|
|
||||||
public partial class WireMockServer
|
public partial class WireMockServer
|
||||||
{
|
{
|
||||||
|
#if OPENAPIPARSER
|
||||||
|
private readonly WireMockOpenApiParserSettings _openApiParserSettings = new WireMockOpenApiParserSettings
|
||||||
|
{
|
||||||
|
PathPatternToUse = ExampleValueType.Regex,
|
||||||
|
HeaderPatternToUse = ExampleValueType.Regex,
|
||||||
|
QueryParameterPatternToUse = ExampleValueType.Regex
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
private IResponseMessage OpenApiConvertToMappings(IRequestMessage requestMessage)
|
private IResponseMessage OpenApiConvertToMappings(IRequestMessage requestMessage)
|
||||||
{
|
{
|
||||||
#if OPENAPIPARSER
|
#if OPENAPIPARSER
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body, out var diagnostic);
|
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body, out var diagnostic);
|
||||||
return diagnostic.Errors.Any() ? ToJson(diagnostic, false, HttpStatusCode.BadRequest) : ToJson(mappingModels);
|
if (diagnostic.Errors.Any())
|
||||||
|
{
|
||||||
|
var diagnosticAsJson = JsonConvert.SerializeObject(diagnostic, JsonSerializationConstants.JsonSerializerSettingsDefault);
|
||||||
|
_settings.Logger.Warn("OpenApiError(s) while converting OpenAPI specification to MappingModel(s) : {0}", diagnosticAsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ToJson(mappingModels);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -35,7 +54,8 @@ public partial class WireMockServer
|
|||||||
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body, out var diagnostic);
|
var mappingModels = new WireMockOpenApiParser().FromText(requestMessage.Body, out var diagnostic);
|
||||||
if (diagnostic.Errors.Any())
|
if (diagnostic.Errors.Any())
|
||||||
{
|
{
|
||||||
return ToJson(diagnostic, false, HttpStatusCode.BadRequest);
|
var diagnosticAsJson = JsonConvert.SerializeObject(diagnostic, JsonSerializationConstants.JsonSerializerSettingsDefault);
|
||||||
|
_settings.Logger.Warn("OpenApiError(s) while converting OpenAPI specification to MappingModel(s) : {0}", diagnosticAsJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertMappingsAndRegisterAsRespondProvider(mappingModels);
|
ConvertMappingsAndRegisterAsRespondProvider(mappingModels);
|
||||||
|
|||||||
@@ -1,21 +1,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using WireMock.Extensions;
|
|
||||||
|
|
||||||
namespace WireMock.Settings;
|
namespace WireMock.Settings;
|
||||||
|
|
||||||
// Based on http://blog.gauffin.org/2014/12/simple-command-line-parser/
|
// Based on http://blog.gauffin.org/2014/12/simple-command-line-parser/
|
||||||
internal class SimpleSettingsParser
|
internal class SimpleCommandLineParser
|
||||||
{
|
{
|
||||||
private const string Sigil = "--";
|
private const string Sigil = "--";
|
||||||
private const string Prefix = $"{nameof(WireMockServerSettings)}__";
|
|
||||||
private static readonly int PrefixLength = Prefix.Length;
|
|
||||||
|
|
||||||
private IDictionary<string, string[]> Arguments { get; } = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
private IDictionary<string, string[]> Arguments { get; } = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public void Parse(string[] arguments, IDictionary? environment = null)
|
public void Parse(string[] arguments)
|
||||||
{
|
{
|
||||||
string currentName = string.Empty;
|
string currentName = string.Empty;
|
||||||
|
|
||||||
@@ -48,18 +44,6 @@ internal class SimpleSettingsParser
|
|||||||
{
|
{
|
||||||
Arguments[currentName] = values.ToArray();
|
Arguments[currentName] = values.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now also parse environment
|
|
||||||
if (environment != null)
|
|
||||||
{
|
|
||||||
foreach (string key in environment.Keys)
|
|
||||||
{
|
|
||||||
if (key.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase) && environment.TryGetStringValue(key, out var value))
|
|
||||||
{
|
|
||||||
Arguments[key.Substring(PrefixLength)] = value.Split(' ').ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Contains(string name)
|
public bool Contains(string name)
|
||||||
@@ -101,16 +85,7 @@ internal class SimpleSettingsParser
|
|||||||
return Contains(name);
|
return Contains(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? GetIntValue(string name)
|
public int? GetIntValue(string name, int? defaultValue = null)
|
||||||
{
|
|
||||||
return GetValue<int?>(name, values =>
|
|
||||||
{
|
|
||||||
var value = values.FirstOrDefault();
|
|
||||||
return !string.IsNullOrEmpty(value) ? int.Parse(value) : null;
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetIntValue(string name, int defaultValue)
|
|
||||||
{
|
{
|
||||||
return GetValue(name, values =>
|
return GetValue(name, values =>
|
||||||
{
|
{
|
||||||
@@ -22,8 +22,6 @@ namespace WireMock.Settings;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class WireMockServerSettings
|
public class WireMockServerSettings
|
||||||
{
|
{
|
||||||
internal const int DefaultStartTimeout = 10000;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the http port.
|
/// Gets or sets the http port.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -83,7 +81,7 @@ public class WireMockServerSettings
|
|||||||
/// StartTimeout
|
/// StartTimeout
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public int StartTimeout { get; set; } = DefaultStartTimeout;
|
public int StartTimeout { get; set; } = 10000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allow Partial Mapping (default set to false).
|
/// Allow Partial Mapping (default set to false).
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -19,16 +18,16 @@ public static class WireMockServerSettingsParser
|
|||||||
/// Parse commandline arguments into WireMockServerSettings.
|
/// Parse commandline arguments into WireMockServerSettings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">The commandline arguments</param>
|
/// <param name="args">The commandline arguments</param>
|
||||||
/// <param name="environment">The environment settings (optional)</param>
|
|
||||||
/// <param name="logger">The logger (optional, can be null)</param>
|
/// <param name="logger">The logger (optional, can be null)</param>
|
||||||
/// <param name="settings">The parsed settings</param>
|
/// <param name="settings">The parsed settings</param>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public static bool TryParseArguments(string[] args, IDictionary? environment, [NotNullWhen(true)] out WireMockServerSettings? settings, IWireMockLogger? logger = null)
|
public static bool TryParseArguments(string[] args, [NotNullWhen(true)] out WireMockServerSettings? settings,
|
||||||
|
IWireMockLogger? logger = null)
|
||||||
{
|
{
|
||||||
Guard.HasNoNulls(args);
|
Guard.HasNoNulls(args);
|
||||||
|
|
||||||
var parser = new SimpleSettingsParser();
|
var parser = new SimpleCommandLineParser();
|
||||||
parser.Parse(args, environment);
|
parser.Parse(args);
|
||||||
|
|
||||||
if (parser.GetBoolSwitchValue("help"))
|
if (parser.GetBoolSwitchValue("help"))
|
||||||
{
|
{
|
||||||
@@ -56,7 +55,6 @@ public static class WireMockServerSettingsParser
|
|||||||
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
|
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
|
||||||
SaveUnmatchedRequests = parser.GetBoolValue(nameof(WireMockServerSettings.SaveUnmatchedRequests)),
|
SaveUnmatchedRequests = parser.GetBoolValue(nameof(WireMockServerSettings.SaveUnmatchedRequests)),
|
||||||
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
||||||
StartTimeout = parser.GetIntValue(nameof(WireMockServerSettings.StartTimeout), WireMockServerSettings.DefaultStartTimeout),
|
|
||||||
ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails"),
|
ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails"),
|
||||||
UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true),
|
UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true),
|
||||||
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
||||||
@@ -81,7 +79,8 @@ public static class WireMockServerSettingsParser
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseLoggerSettings(WireMockServerSettings settings, IWireMockLogger? logger, SimpleSettingsParser parser)
|
private static void ParseLoggerSettings(WireMockServerSettings settings, IWireMockLogger? logger,
|
||||||
|
SimpleCommandLineParser parser)
|
||||||
{
|
{
|
||||||
var loggerType = parser.GetStringValue("WireMockLogger");
|
var loggerType = parser.GetStringValue("WireMockLogger");
|
||||||
switch (loggerType)
|
switch (loggerType)
|
||||||
@@ -104,7 +103,7 @@ public static class WireMockServerSettingsParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseProxyAndRecordSettings(WireMockServerSettings settings, SimpleSettingsParser parser)
|
private static void ParseProxyAndRecordSettings(WireMockServerSettings settings, SimpleCommandLineParser parser)
|
||||||
{
|
{
|
||||||
var proxyUrl = parser.GetStringValue("ProxyURL") ?? parser.GetStringValue("ProxyUrl");
|
var proxyUrl = parser.GetStringValue("ProxyURL") ?? parser.GetStringValue("ProxyUrl");
|
||||||
if (!string.IsNullOrEmpty(proxyUrl))
|
if (!string.IsNullOrEmpty(proxyUrl))
|
||||||
@@ -136,7 +135,7 @@ public static class WireMockServerSettingsParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParsePortSettings(WireMockServerSettings settings, SimpleSettingsParser parser)
|
private static void ParsePortSettings(WireMockServerSettings settings, SimpleCommandLineParser parser)
|
||||||
{
|
{
|
||||||
if (parser.Contains(nameof(WireMockServerSettings.Port)))
|
if (parser.Contains(nameof(WireMockServerSettings.Port)))
|
||||||
{
|
{
|
||||||
@@ -148,7 +147,7 @@ public static class WireMockServerSettingsParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseCertificateSettings(WireMockServerSettings settings, SimpleSettingsParser parser)
|
private static void ParseCertificateSettings(WireMockServerSettings settings, SimpleCommandLineParser parser)
|
||||||
{
|
{
|
||||||
var certificateSettings = new WireMockCertificateSettings
|
var certificateSettings = new WireMockCertificateSettings
|
||||||
{
|
{
|
||||||
@@ -164,7 +163,7 @@ public static class WireMockServerSettingsParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseWebProxyAddressSettings(ProxyAndRecordSettings settings, SimpleSettingsParser parser)
|
private static void ParseWebProxyAddressSettings(ProxyAndRecordSettings settings, SimpleCommandLineParser parser)
|
||||||
{
|
{
|
||||||
string? proxyAddress = parser.GetStringValue("WebProxyAddress");
|
string? proxyAddress = parser.GetStringValue("WebProxyAddress");
|
||||||
if (!string.IsNullOrEmpty(proxyAddress))
|
if (!string.IsNullOrEmpty(proxyAddress))
|
||||||
@@ -178,7 +177,7 @@ public static class WireMockServerSettingsParser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ParseProxyUrlReplaceSettings(ProxyAndRecordSettings settings, SimpleSettingsParser parser)
|
private static void ParseProxyUrlReplaceSettings(ProxyAndRecordSettings settings, SimpleCommandLineParser parser)
|
||||||
{
|
{
|
||||||
var proxyUrlReplaceOldValue = parser.GetStringValue("ProxyUrlReplaceOldValue");
|
var proxyUrlReplaceOldValue = parser.GetStringValue("ProxyUrlReplaceOldValue");
|
||||||
var proxyUrlReplaceNewValue = parser.GetStringValue("ProxyUrlReplaceNewValue");
|
var proxyUrlReplaceNewValue = parser.GetStringValue("ProxyUrlReplaceNewValue");
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ internal static class CSharpFormatter
|
|||||||
return "\"\"";
|
return "\"\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.Contains('\n'))
|
if (value.Contains("\n"))
|
||||||
{
|
{
|
||||||
var escapedValue = value?.Replace("\"", "\"\"") ?? string.Empty;
|
var escapedValue = value?.Replace("\"", "\"\"") ?? string.Empty;
|
||||||
return $"@\"{escapedValue}\"";
|
return $"@\"{escapedValue}\"";
|
||||||
|
|||||||
@@ -50,19 +50,16 @@
|
|||||||
<DefineConstants>$(DefineConstants);OPENAPIPARSER</DefineConstants>
|
<DefineConstants>$(DefineConstants);OPENAPIPARSER</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
|
||||||
<DefineConstants>$(DefineConstants);GRAPHQL</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Util\FileSystemWatcherExtensions.cs" />
|
<Compile Remove="Util\FileSystemWatcherExtensions.cs" />
|
||||||
|
<Compile Remove="Matchers\Request\IRequestMatcher.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" />
|
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" />
|
||||||
<PackageReference Include="JsonConverter.Abstractions" Version="0.4.0" />
|
<PackageReference Include="JsonConverter.Abstractions" Version="0.4.0" />
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
|
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
|
||||||
<PackageReference Include="NSwag.Core" Version="13.16.1" />
|
<PackageReference Include="NSwag.Core" Version="13.16.1" />
|
||||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||||
@@ -157,11 +154,6 @@
|
|||||||
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
|
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
|
||||||
<PackageReference Include="GraphQL" Version="7.5.0" />
|
|
||||||
<PackageReference Include="GraphQL.NewtonsoftJson" Version="7.5.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||||
<PackageReference Include="Nullable" Version="1.3.1">
|
<PackageReference Include="Nullable" Version="1.3.1">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
using System.Collections;
|
|
||||||
using FluentAssertions;
|
|
||||||
using WireMock.Extensions;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.Extensions;
|
|
||||||
|
|
||||||
public class DictionaryExtensionsTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void TryGetStringValue_WhenKeyExistsAndValueIsString_ReturnsTrueAndStringValue()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var dictionary = new Hashtable { { "key", "value" } };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = dictionary.TryGetStringValue("key", out var value);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().BeTrue();
|
|
||||||
value.Should().Be("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void TryGetStringValue_WhenKeyExistsAndValueIsNotString_ReturnsTrueAndStringValue()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var dictionary = new Hashtable { { "key", 123 } };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = dictionary.TryGetStringValue("key", out var value);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().BeTrue();
|
|
||||||
value.Should().Be("123");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void TryGetStringValue_WhenKeyDoesNotExist_ReturnsFalseAndNull()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var dictionary = new Hashtable { { "otherKey", "value" } };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = dictionary.TryGetStringValue("key", out var value);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().BeFalse();
|
|
||||||
value.Should().BeNull();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -210,36 +210,6 @@ public class WireMockAssertionsTests : IDisposable
|
|||||||
.Be($"{string.Join(NewLine, missingValue1Message, missingValue2Message)}{NewLine}");
|
.Be($"{string.Join(NewLine, missingValue1Message, missingValue2Message)}{NewLine}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task HaveReceivedACall_WithHeader_ShouldCheckAllRequests()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
using var server = WireMockServer.Start();
|
|
||||||
using var client = server.CreateClient();
|
|
||||||
|
|
||||||
// Act 1
|
|
||||||
await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
|
|
||||||
{
|
|
||||||
Headers =
|
|
||||||
{
|
|
||||||
Authorization = new AuthenticationHeaderValue("Bearer", "invalidToken")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act 2
|
|
||||||
await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
|
|
||||||
{
|
|
||||||
Headers =
|
|
||||||
{
|
|
||||||
Authorization = new AuthenticationHeaderValue("Bearer", "validToken")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
server.Should().HaveReceivedACall().WithHeader("Authorization", "Bearer invalidToken");
|
|
||||||
server.Should().HaveReceivedACall().WithHeader("Authorization", "Bearer validToken");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task HaveReceivedACall_AtUrl_WhenACallWasMadeToUrl_Should_BeOK()
|
public async Task HaveReceivedACall_AtUrl_WhenACallWasMadeToUrl_Should_BeOK()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
using NFluent;
|
using NFluent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
|
||||||
using WireMock.Http;
|
using WireMock.Http;
|
||||||
using WireMock.Models;
|
using WireMock.Models;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
@@ -162,29 +160,4 @@ public class HttpRequestMessageHelperTests
|
|||||||
// Assert
|
// Assert
|
||||||
Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/xml; charset=Ascii");
|
Check.That(message.Content.Headers.GetValues("Content-Type")).ContainsExactly("application/xml; charset=Ascii");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("HEAD", true)]
|
|
||||||
[InlineData("GET", false)]
|
|
||||||
[InlineData("PUT", false)]
|
|
||||||
[InlineData("POST", false)]
|
|
||||||
[InlineData("DELETE", false)]
|
|
||||||
[InlineData("TRACE", false)]
|
|
||||||
[InlineData("OPTIONS", false)]
|
|
||||||
[InlineData("CONNECT", false)]
|
|
||||||
[InlineData("PATCH", false)]
|
|
||||||
public void HttpRequestMessageHelper_Create_ContentLengthAllowedForMethod(string method, bool resultShouldBe)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var key = "Content-Length";
|
|
||||||
var value = 1234;
|
|
||||||
var headers = new Dictionary<string, string[]> { { key, new[] { "1234" } } };
|
|
||||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), method, ClientIp, null, headers);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var message = HttpRequestMessageHelper.Create(request, "http://url");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
message.Content?.Headers.ContentLength.Should().Be(resultShouldBe ? value : null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -14,17 +14,6 @@
|
|||||||
},
|
},
|
||||||
Methods: [
|
Methods: [
|
||||||
GET
|
GET
|
||||||
],
|
|
||||||
Params: [
|
|
||||||
{
|
|
||||||
Name: test,
|
|
||||||
Matchers: [
|
|
||||||
{
|
|
||||||
Name: LinqMatcher,
|
|
||||||
Pattern: it.Length < 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
Response: {
|
Response: {
|
||||||
|
|||||||
@@ -14,17 +14,6 @@
|
|||||||
},
|
},
|
||||||
Methods: [
|
Methods: [
|
||||||
GET
|
GET
|
||||||
],
|
|
||||||
Params: [
|
|
||||||
{
|
|
||||||
Name: test,
|
|
||||||
Matchers: [
|
|
||||||
{
|
|
||||||
Name: LinqMatcher,
|
|
||||||
Pattern: it.Length < 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
Response: {
|
Response: {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using VerifyTests;
|
|||||||
using VerifyXunit;
|
using VerifyXunit;
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Matchers;
|
|
||||||
using WireMock.Net.Tests.VerifyExtensions;
|
using WireMock.Net.Tests.VerifyExtensions;
|
||||||
using WireMock.Owin;
|
using WireMock.Owin;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
@@ -66,7 +65,6 @@ public class MappingBuilderTests
|
|||||||
|
|
||||||
_sut.Given(Request.Create()
|
_sut.Given(Request.Create()
|
||||||
.WithPath("/foo")
|
.WithPath("/foo")
|
||||||
.WithParam("test", new LinqMatcher("it.Length < 10"))
|
|
||||||
.UsingGet()
|
.UsingGet()
|
||||||
)
|
)
|
||||||
.WithGuid(MappingGuid)
|
.WithGuid(MappingGuid)
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
#if GRAPHQL
|
|
||||||
using System;
|
|
||||||
using FluentAssertions;
|
|
||||||
using GraphQLParser.Exceptions;
|
|
||||||
using WireMock.Matchers;
|
|
||||||
using WireMock.Models;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.Matchers;
|
|
||||||
|
|
||||||
public class GraphQLMatcherTests
|
|
||||||
{
|
|
||||||
private const string TestSchema = @"
|
|
||||||
input MessageInput {
|
|
||||||
content: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Message {
|
|
||||||
id: ID!
|
|
||||||
content: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mutation {
|
|
||||||
createMessage(input: MessageInput): Message
|
|
||||||
updateMessage(id: ID!, input: MessageInput): Message
|
|
||||||
}
|
|
||||||
|
|
||||||
type Query {
|
|
||||||
greeting:String
|
|
||||||
students:[Student]
|
|
||||||
studentById(id:ID!):Student
|
|
||||||
}
|
|
||||||
|
|
||||||
type Student {
|
|
||||||
id:ID!
|
|
||||||
firstName:String
|
|
||||||
lastName:String
|
|
||||||
fullName:String
|
|
||||||
}";
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GraphQLMatcher_For_ValidSchema_And_CorrectQuery_IsMatch()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var input = "{\"query\":\"{\\r\\n students {\\r\\n fullName\\r\\n id\\r\\n }\\r\\n}\"}";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var matcher = new GraphQLMatcher(TestSchema);
|
|
||||||
var result = matcher.IsMatch(input);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().Be(MatchScores.Perfect);
|
|
||||||
|
|
||||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GraphQLMatcher_For_ValidSchema_And_CorrectGraphQLQuery_IsMatch()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var input = @"{
|
|
||||||
""query"": ""query ($sid: ID!)\r\n{\r\n studentById(id: $sid) {\r\n fullName\r\n id\r\n }\r\n}"",
|
|
||||||
""variables"": {
|
|
||||||
""sid"": ""1""
|
|
||||||
}
|
|
||||||
}";
|
|
||||||
// Act
|
|
||||||
var matcher = new GraphQLMatcher(TestSchema);
|
|
||||||
var result = matcher.IsMatch(input);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().Be(MatchScores.Perfect);
|
|
||||||
|
|
||||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQuery_IsMismatch()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var input = @"
|
|
||||||
{
|
|
||||||
students {
|
|
||||||
fullName
|
|
||||||
id
|
|
||||||
abc
|
|
||||||
}
|
|
||||||
}";
|
|
||||||
// Act
|
|
||||||
var matcher = new GraphQLMatcher(TestSchema);
|
|
||||||
var result = matcher.IsMatch(input);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().Be(MatchScores.Mismatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GraphQLMatcher_For_ValidSchemaAsStringPattern_And_CorrectQuery_IsMatch()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var input = "{\"query\":\"{\\r\\n students {\\r\\n fullName\\r\\n id\\r\\n }\\r\\n}\"}";
|
|
||||||
var schema = new StringPattern
|
|
||||||
{
|
|
||||||
Pattern = TestSchema
|
|
||||||
};
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var matcher = new GraphQLMatcher(schema);
|
|
||||||
var result = matcher.IsMatch(input);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
result.Should().Be(MatchScores.Perfect);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQueryWithError_WithThrowExceptionTrue_ThrowsException()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var input = "{\"query\":\"{\\r\\n studentsX {\\r\\n fullName\\r\\n X\\r\\n }\\r\\n}\"}";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var matcher = new GraphQLMatcher(TestSchema, MatchBehaviour.AcceptOnMatch, true);
|
|
||||||
Action action = () => matcher.IsMatch(input);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
action.Should().Throw<Exception>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GraphQLMatcher_For_InvalidSchema_ThrowsGraphQLSyntaxErrorException()
|
|
||||||
{
|
|
||||||
// Act
|
|
||||||
// ReSharper disable once ObjectCreationAsStatement
|
|
||||||
Action action = () => _ = new GraphQLMatcher("in va lid");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
action.Should().Throw<GraphQLSyntaxErrorException>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -11,7 +11,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_GetName()
|
public void JsonPathMatcher_GetName()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher("X");
|
var matcher = new JsonPathMatcher("X");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -24,7 +24,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_GetPatterns()
|
public void JsonPathMatcher_GetPatterns()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher("X");
|
var matcher = new JsonPathMatcher("X");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -37,7 +37,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_ByteArray()
|
public void JsonPathMatcher_IsMatch_ByteArray()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var bytes = EmptyArray<byte>.Value;
|
var bytes = EmptyArray<byte>.Value;
|
||||||
var matcher = new JsonPathMatcher("");
|
var matcher = new JsonPathMatcher("");
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_NullString()
|
public void JsonPathMatcher_IsMatch_NullString()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
string? s = null;
|
string? s = null;
|
||||||
var matcher = new JsonPathMatcher("");
|
var matcher = new JsonPathMatcher("");
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_NullObject()
|
public void JsonPathMatcher_IsMatch_NullObject()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
object? o = null;
|
object? o = null;
|
||||||
var matcher = new JsonPathMatcher("");
|
var matcher = new JsonPathMatcher("");
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_String_Exception_Mismatch()
|
public void JsonPathMatcher_IsMatch_String_Exception_Mismatch()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher("xxx");
|
var matcher = new JsonPathMatcher("xxx");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -92,7 +92,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch()
|
public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher("");
|
var matcher = new JsonPathMatcher("");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -105,7 +105,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_AnonymousObject()
|
public void JsonPathMatcher_IsMatch_AnonymousObject()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -115,51 +115,10 @@ public class JsonPathMatcherTests
|
|||||||
Check.That(match).IsEqualTo(1);
|
Check.That(match).IsEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void JsonPathMatcher_IsMatch_AnonymousObject_WithNestedObject()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
double match = matcher.IsMatch(new { things = new { name = "x" } });
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(match).IsEqualTo(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void JsonPathMatcher_IsMatch_String_WithNestedObject()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var json = "{ \"things\": { \"name\": \"x\" } }";
|
|
||||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
double match = matcher.IsMatch(json);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(match).IsEqualTo(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void JsonPathMatcher_IsNoMatch_String_WithNestedObject()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var json = "{ \"things\": { \"name\": \"y\" } }";
|
|
||||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
double match = matcher.IsMatch(json);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(match).IsEqualTo(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_JObject()
|
public void JsonPathMatcher_IsMatch_JObject()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
string[] patterns = { "$..[?(@.Id == 1)]" };
|
string[] patterns = { "$..[?(@.Id == 1)]" };
|
||||||
var matcher = new JsonPathMatcher(patterns);
|
var matcher = new JsonPathMatcher(patterns);
|
||||||
|
|
||||||
@@ -178,7 +137,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_JObject_Parsed()
|
public void JsonPathMatcher_IsMatch_JObject_Parsed()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -191,7 +150,7 @@ public class JsonPathMatcherTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void JsonPathMatcher_IsMatch_RejectOnMatch()
|
public void JsonPathMatcher_IsMatch_RejectOnMatch()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Assign
|
||||||
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "$..[?(@.Id == 1)]");
|
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "$..[?(@.Id == 1)]");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|||||||
@@ -42,14 +42,7 @@ public class PactTests
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
var folder = Path.Combine("../../../", "Pact", "files");
|
server.SavePact(Path.Combine("../../../", "Pact", "files"), "pact-get.json");
|
||||||
var file = "pact-get.json";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
server.SavePact(folder, file);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
File.ReadAllBytes(Path.Combine(folder, file)).Length.Should().BeGreaterThan(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -208,13 +201,6 @@ public class PactTests
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
var folder = Path.Combine("../../../", "Pact", "files");
|
server.SavePact(Path.Combine("../../../", "Pact", "files"), "pact-multiple.json");
|
||||||
var file = "pact-multiple.json";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
server.SavePact(folder, file);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
File.ReadAllBytes(Path.Combine(folder, file)).Length.Should().BeGreaterThan(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#if GRAPHQL
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using FluentAssertions;
|
|
||||||
using GraphQL.Types;
|
|
||||||
using WireMock.Matchers;
|
|
||||||
using WireMock.Matchers.Request;
|
|
||||||
using WireMock.RequestBuilders;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.RequestBuilders;
|
|
||||||
|
|
||||||
public class RequestBuilderWithGraphQLSchemaTests
|
|
||||||
{
|
|
||||||
private const string TestSchema = @"
|
|
||||||
input MessageInput {
|
|
||||||
content: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Message {
|
|
||||||
id: ID!
|
|
||||||
content: String
|
|
||||||
author: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Mutation {
|
|
||||||
createMessage(input: MessageInput): Message
|
|
||||||
updateMessage(id: ID!, input: MessageInput): Message
|
|
||||||
}
|
|
||||||
|
|
||||||
type Query {
|
|
||||||
greeting:String
|
|
||||||
students:[Student]
|
|
||||||
studentById(id:ID!):Student
|
|
||||||
}
|
|
||||||
|
|
||||||
type Student {
|
|
||||||
id:ID!
|
|
||||||
firstName:String
|
|
||||||
lastName:String
|
|
||||||
fullName:String
|
|
||||||
}";
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void RequestBuilder_WithGraphQLSchema_SchemaAsString()
|
|
||||||
{
|
|
||||||
// Act
|
|
||||||
var requestBuilder = (Request)Request.Create().WithGraphQLSchema(TestSchema);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
|
||||||
matchers.Should().HaveCount(1);
|
|
||||||
((RequestMessageGraphQLMatcher)matchers[0]).Matchers.Should().ContainItemsAssignableTo<GraphQLMatcher>();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void RequestBuilder_WithGraphQLSchema_SchemaAsISchema()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var schema = Schema.For(TestSchema);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var requestBuilder = (Request)Request.Create().WithGraphQLSchema(schema);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
|
||||||
matchers.Should().HaveCount(1);
|
|
||||||
((RequestMessageGraphQLMatcher)matchers[0]).Matchers.Should().ContainItemsAssignableTo<GraphQLMatcher>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
#if GRAPHQL
|
|
||||||
using System.Linq;
|
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using WireMock.Matchers;
|
|
||||||
using WireMock.Matchers.Request;
|
|
||||||
using WireMock.Models;
|
|
||||||
using WireMock.Types;
|
|
||||||
using WireMock.Util;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.RequestMatchers;
|
|
||||||
|
|
||||||
public class RequestMessageGraphQLMatcherTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatcher()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var body = new BodyData
|
|
||||||
{
|
|
||||||
BodyAsString = "b",
|
|
||||||
DetectedBodyType = BodyType.String
|
|
||||||
};
|
|
||||||
var stringMatcherMock = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(1d);
|
|
||||||
|
|
||||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
|
||||||
|
|
||||||
var matcher = new RequestMessageGraphQLMatcher(stringMatcherMock.Object);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = new RequestMatchResult();
|
|
||||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
score.Should().Be(MatchScores.Perfect);
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
stringMatcherMock.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(1d, 1d, 1d)]
|
|
||||||
[InlineData(0d, 1d, 1d)]
|
|
||||||
[InlineData(1d, 0d, 1d)]
|
|
||||||
[InlineData(0d, 0d, 0d)]
|
|
||||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatchers_Or(double one, double two, double expected)
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var body = new BodyData
|
|
||||||
{
|
|
||||||
BodyAsString = "b",
|
|
||||||
DetectedBodyType = BodyType.String
|
|
||||||
};
|
|
||||||
var stringMatcherMock1 = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock1.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(one);
|
|
||||||
|
|
||||||
var stringMatcherMock2 = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock2.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(two);
|
|
||||||
|
|
||||||
var matchers = new[] { stringMatcherMock1.Object, stringMatcherMock2.Object };
|
|
||||||
|
|
||||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
|
||||||
|
|
||||||
var matcher = new RequestMessageGraphQLMatcher(MatchOperator.Or, matchers.Cast<IMatcher>().ToArray());
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = new RequestMatchResult();
|
|
||||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
score.Should().Be(expected);
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
stringMatcherMock1.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock1.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
|
|
||||||
stringMatcherMock2.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock2.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
stringMatcherMock2.VerifyNoOtherCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(1d, 1d, 1d)]
|
|
||||||
[InlineData(0d, 1d, 0d)]
|
|
||||||
[InlineData(1d, 0d, 0d)]
|
|
||||||
[InlineData(0d, 0d, 0d)]
|
|
||||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatchers_And(double one, double two, double expected)
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var body = new BodyData
|
|
||||||
{
|
|
||||||
BodyAsString = "b",
|
|
||||||
DetectedBodyType = BodyType.String
|
|
||||||
};
|
|
||||||
var stringMatcherMock1 = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock1.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(one);
|
|
||||||
|
|
||||||
var stringMatcherMock2 = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock2.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(two);
|
|
||||||
|
|
||||||
var matchers = new[] { stringMatcherMock1.Object, stringMatcherMock2.Object };
|
|
||||||
|
|
||||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
|
||||||
|
|
||||||
var matcher = new RequestMessageGraphQLMatcher(MatchOperator.And, matchers.Cast<IMatcher>().ToArray());
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = new RequestMatchResult();
|
|
||||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
score.Should().Be(expected);
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
stringMatcherMock1.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock1.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
|
|
||||||
stringMatcherMock2.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock2.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
stringMatcherMock2.VerifyNoOtherCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(1d, 1d, 1d)]
|
|
||||||
[InlineData(0d, 1d, 0.5d)]
|
|
||||||
[InlineData(1d, 0d, 0.5d)]
|
|
||||||
[InlineData(0d, 0d, 0d)]
|
|
||||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatchers_Average(double one, double two, double expected)
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var body = new BodyData
|
|
||||||
{
|
|
||||||
BodyAsString = "b",
|
|
||||||
DetectedBodyType = BodyType.String
|
|
||||||
};
|
|
||||||
var stringMatcherMock1 = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock1.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(one);
|
|
||||||
|
|
||||||
var stringMatcherMock2 = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock2.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(two);
|
|
||||||
|
|
||||||
var matchers = new[] { stringMatcherMock1.Object, stringMatcherMock2.Object };
|
|
||||||
|
|
||||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
|
||||||
|
|
||||||
var matcher = new RequestMessageGraphQLMatcher(MatchOperator.Average, matchers.Cast<IMatcher>().ToArray());
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = new RequestMatchResult();
|
|
||||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
score.Should().Be(expected);
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
stringMatcherMock1.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock1.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
|
|
||||||
stringMatcherMock2.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock2.Verify(m => m.IsMatch("b"), Times.Once);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsBytes_IStringMatcher_ReturnMisMatch()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var body = new BodyData
|
|
||||||
{
|
|
||||||
BodyAsBytes = new byte[] { 1 },
|
|
||||||
DetectedBodyType = BodyType.Bytes
|
|
||||||
};
|
|
||||||
var stringMatcherMock = new Mock<IStringMatcher>();
|
|
||||||
stringMatcherMock.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(0.5d);
|
|
||||||
|
|
||||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
|
||||||
|
|
||||||
var matcher = new RequestMessageGraphQLMatcher(stringMatcherMock.Object);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = new RequestMatchResult();
|
|
||||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
score.Should().Be(MatchScores.Mismatch);
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
stringMatcherMock.Verify(m => m.GetPatterns(), Times.Never);
|
|
||||||
stringMatcherMock.Verify(m => m.IsMatch(It.IsAny<string>()), Times.Never);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{
|
|
||||||
Guid: Guid_1,
|
|
||||||
UpdatedAt: DateTime_1,
|
|
||||||
Title: ,
|
|
||||||
Description: ,
|
|
||||||
Priority: 42,
|
|
||||||
Request: {
|
|
||||||
Body: {
|
|
||||||
Matcher: {
|
|
||||||
Name: GraphQLMatcher,
|
|
||||||
Pattern:
|
|
||||||
type Query {
|
|
||||||
greeting:String
|
|
||||||
students:[Student]
|
|
||||||
studentById(id:ID!):Student
|
|
||||||
}
|
|
||||||
|
|
||||||
type Student {
|
|
||||||
id:ID!
|
|
||||||
firstName:String
|
|
||||||
lastName:String
|
|
||||||
fullName:String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Response: {},
|
|
||||||
UseWebhooksFireAndForget: false
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
Guid: Guid_1,
|
|
||||||
UpdatedAt: DateTime_1,
|
|
||||||
Title: ,
|
|
||||||
Description: ,
|
|
||||||
Priority: 42,
|
|
||||||
Request: {
|
|
||||||
Path: {
|
|
||||||
Matchers: [
|
|
||||||
{
|
|
||||||
Name: WildcardMatcher,
|
|
||||||
Pattern: 1.2.3.4,
|
|
||||||
IgnoreCase: false
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Response: {},
|
|
||||||
UseWebhooksFireAndForget: false
|
|
||||||
}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -260,7 +260,7 @@ public partial class MappingConverterTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public Task ToMappingModel_WithDelay_ReturnsCorrectModel()
|
public Task ToMappingModel_WithDelayAsMilliSeconds_ReturnsCorrectModel()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
var delay = 1000;
|
var delay = 1000;
|
||||||
@@ -343,56 +343,5 @@ public partial class MappingConverterTests
|
|||||||
// Verify
|
// Verify
|
||||||
return Verifier.Verify(model);
|
return Verifier.Verify(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public Task ToMappingModel_Request_WithClientIP_ReturnsCorrectModel()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var request = Request.Create().WithClientIP("1.2.3.4");
|
|
||||||
var response = Response.Create();
|
|
||||||
var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 42, null, null, null, null, null, false, null, null, null);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var model = _sut.ToMappingModel(mapping);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
model.Should().NotBeNull();
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
return Verifier.Verify(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GRAPHQL
|
|
||||||
[Fact]
|
|
||||||
public Task ToMappingModel_Request_WithBodyAsGraphQLSchema_ReturnsCorrectModel()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var schema = @"
|
|
||||||
type Query {
|
|
||||||
greeting:String
|
|
||||||
students:[Student]
|
|
||||||
studentById(id:ID!):Student
|
|
||||||
}
|
|
||||||
|
|
||||||
type Student {
|
|
||||||
id:ID!
|
|
||||||
firstName:String
|
|
||||||
lastName:String
|
|
||||||
fullName:String
|
|
||||||
}";
|
|
||||||
var request = Request.Create().WithBodyAsGraphQLSchema(schema);
|
|
||||||
var response = Response.Create();
|
|
||||||
var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 42, null, null, null, null, null, false, null, null, null);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var model = _sut.ToMappingModel(mapping);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
model.Should().NotBeNull();
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
return Verifier.Verify(model);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
102
test/WireMock.Net.Tests/Settings/SimpleCommandLineParserTests.cs
Normal file
102
test/WireMock.Net.Tests/Settings/SimpleCommandLineParserTests.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using NFluent;
|
||||||
|
using WireMock.Settings;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.Settings;
|
||||||
|
|
||||||
|
public class SimpleCommandLineParserTests
|
||||||
|
{
|
||||||
|
private readonly SimpleCommandLineParser _parser;
|
||||||
|
|
||||||
|
public SimpleCommandLineParserTests()
|
||||||
|
{
|
||||||
|
_parser = new SimpleCommandLineParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleCommandLineParser_Parse_Arguments()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
_parser.Parse(new[] { "--test1", "one", "--test2", "two", "--test3", "three" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string? value1 = _parser.GetStringValue("test1");
|
||||||
|
string? value2 = _parser.GetStringValue("test2");
|
||||||
|
string? value3 = _parser.GetStringValue("test3");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(value1).IsEqualTo("one");
|
||||||
|
Check.That(value2).IsEqualTo("two");
|
||||||
|
Check.That(value3).IsEqualTo("three");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleCommandLineParser_Parse_ArgumentsAsCombinedKeyAndValue()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
_parser.Parse(new[] { "--test1 one", "--test2 two", "--test3 three" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string? value1 = _parser.GetStringValue("test1");
|
||||||
|
string? value2 = _parser.GetStringValue("test2");
|
||||||
|
string? value3 = _parser.GetStringValue("test3");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(value1).IsEqualTo("one");
|
||||||
|
Check.That(value2).IsEqualTo("two");
|
||||||
|
Check.That(value3).IsEqualTo("three");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleCommandLineParser_Parse_ArgumentsMixed()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
_parser.Parse(new[] { "--test1 one", "--test2", "two", "--test3 three" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
string? value1 = _parser.GetStringValue("test1");
|
||||||
|
string? value2 = _parser.GetStringValue("test2");
|
||||||
|
string? value3 = _parser.GetStringValue("test3");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(value1).IsEqualTo("one");
|
||||||
|
Check.That(value2).IsEqualTo("two");
|
||||||
|
Check.That(value3).IsEqualTo("three");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleCommandLineParser_Parse_GetBoolValue()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
_parser.Parse(new[] { "'--test1", "false'", "--test2 true" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
bool value1 = _parser.GetBoolValue("test1");
|
||||||
|
bool value2 = _parser.GetBoolValue("test2");
|
||||||
|
bool value3 = _parser.GetBoolValue("test3", true);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(value1).IsEqualTo(false);
|
||||||
|
Check.That(value2).IsEqualTo(true);
|
||||||
|
Check.That(value3).IsEqualTo(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleCommandLineParser_Parse_GetIntValue()
|
||||||
|
{
|
||||||
|
// Assign
|
||||||
|
_parser.Parse(new[] { "--test1", "42", "--test2 55" });
|
||||||
|
|
||||||
|
// Act
|
||||||
|
int? value1 = _parser.GetIntValue("test1");
|
||||||
|
int? value2 = _parser.GetIntValue("test2");
|
||||||
|
int? value3 = _parser.GetIntValue("test3", 100);
|
||||||
|
int? value4 = _parser.GetIntValue("test4");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Check.That(value1).IsEqualTo(42);
|
||||||
|
Check.That(value2).IsEqualTo(55);
|
||||||
|
Check.That(value3).IsEqualTo(100);
|
||||||
|
Check.That(value4).IsNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using FluentAssertions;
|
|
||||||
using NFluent;
|
|
||||||
using WireMock.Settings;
|
|
||||||
using WireMock.Types;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.Settings;
|
|
||||||
|
|
||||||
public class SimpleSettingsParserTests
|
|
||||||
{
|
|
||||||
private readonly SimpleSettingsParser _parser;
|
|
||||||
|
|
||||||
public SimpleSettingsParserTests()
|
|
||||||
{
|
|
||||||
_parser = new SimpleSettingsParser();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_Arguments()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
_parser.Parse(new[] { "--test1", "one", "--test2", "2", "--test3", "3", "--test4", "true", "--test5", "Https" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
string? stringValue = _parser.GetStringValue("test1");
|
|
||||||
int? intOptional = _parser.GetIntValue("test2");
|
|
||||||
int intWithDefault = _parser.GetIntValue("test3", 42);
|
|
||||||
bool? boolWithDefault = _parser.GetBoolValue("test4");
|
|
||||||
HostingScheme? enumOptional = _parser.GetEnumValue<HostingScheme>("test5");
|
|
||||||
HostingScheme enumWithDefault = _parser.GetEnumValue("test99", HostingScheme.HttpAndHttps);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
stringValue.Should().Be("one");
|
|
||||||
intOptional.Should().Be(2);
|
|
||||||
intWithDefault.Should().Be(3);
|
|
||||||
boolWithDefault.Should().Be(true);
|
|
||||||
enumOptional.Should().Be(HostingScheme.Https);
|
|
||||||
enumWithDefault.Should().Be(HostingScheme.HttpAndHttps);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_Environment()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var env = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "WireMockServerSettings__test1", "one" },
|
|
||||||
{ "WireMockServerSettings__test2", "two" }
|
|
||||||
};
|
|
||||||
_parser.Parse(new string[0], env);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
string? value1 = _parser.GetStringValue("test1");
|
|
||||||
string? value2 = _parser.GetStringValue("test2");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo("one");
|
|
||||||
Check.That(value2).IsEqualTo("two");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_ArgumentsAsCombinedKeyAndValue()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
_parser.Parse(new[] { "--test1 one", "--test2 two", "--test3 three" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
string? value1 = _parser.GetStringValue("test1");
|
|
||||||
string? value2 = _parser.GetStringValue("test2");
|
|
||||||
string? value3 = _parser.GetStringValue("test3");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo("one");
|
|
||||||
Check.That(value2).IsEqualTo("two");
|
|
||||||
Check.That(value3).IsEqualTo("three");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_ArgumentsMixed()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
_parser.Parse(new[] { "--test1 one", "--test2", "two", "--test3 three" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
string? value1 = _parser.GetStringValue("test1");
|
|
||||||
string? value2 = _parser.GetStringValue("test2");
|
|
||||||
string? value3 = _parser.GetStringValue("test3");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo("one");
|
|
||||||
Check.That(value2).IsEqualTo("two");
|
|
||||||
Check.That(value3).IsEqualTo("three");
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_GetBoolValue()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
_parser.Parse(new[] { "'--test1", "false'", "--test2 true" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
bool value1 = _parser.GetBoolValue("test1");
|
|
||||||
bool value2 = _parser.GetBoolValue("test2");
|
|
||||||
bool value3 = _parser.GetBoolValue("test3", true);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo(false);
|
|
||||||
Check.That(value2).IsEqualTo(true);
|
|
||||||
Check.That(value3).IsEqualTo(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_Environment_GetBoolValue()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var env = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "WireMockServerSettings__test1", "false" },
|
|
||||||
{ "WireMockServerSettings__test2", "true" }
|
|
||||||
};
|
|
||||||
_parser.Parse(new string[0], env);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
bool value1 = _parser.GetBoolValue("test1");
|
|
||||||
bool value2 = _parser.GetBoolValue("test2");
|
|
||||||
bool value3 = _parser.GetBoolValue("test3", true);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo(false);
|
|
||||||
Check.That(value2).IsEqualTo(true);
|
|
||||||
Check.That(value3).IsEqualTo(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_GetIntValue()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
_parser.Parse(new[] { "--test1", "42", "--test2 55" });
|
|
||||||
|
|
||||||
// Act
|
|
||||||
int? value1 = _parser.GetIntValue("test1");
|
|
||||||
int? value2 = _parser.GetIntValue("test2");
|
|
||||||
int? value3 = _parser.GetIntValue("test3", 100);
|
|
||||||
int? value4 = _parser.GetIntValue("test4");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo(42);
|
|
||||||
Check.That(value2).IsEqualTo(55);
|
|
||||||
Check.That(value3).IsEqualTo(100);
|
|
||||||
Check.That(value4).IsNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SimpleCommandLineParser_Parse_Environment_GetIntValue()
|
|
||||||
{
|
|
||||||
// Assign
|
|
||||||
var env = new Dictionary<string, string>
|
|
||||||
{
|
|
||||||
{ "WireMockServerSettings__test1", "42" },
|
|
||||||
{ "WireMockServerSETTINGS__TEST2", "55" }
|
|
||||||
};
|
|
||||||
_parser.Parse(new string[0], env);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
int? value1 = _parser.GetIntValue("test1");
|
|
||||||
int? value2 = _parser.GetIntValue("test2");
|
|
||||||
int? value3 = _parser.GetIntValue("test3", 100);
|
|
||||||
int? value4 = _parser.GetIntValue("test4");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Check.That(value1).IsEqualTo(42);
|
|
||||||
Check.That(value2).IsEqualTo(55);
|
|
||||||
Check.That(value3).IsEqualTo(100);
|
|
||||||
Check.That(value4).IsNull();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,12 +24,8 @@
|
|||||||
<DefineConstants>NETFRAMEWORK</DefineConstants>
|
<DefineConstants>NETFRAMEWORK</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
|
||||||
<DefineConstants>$(DefineConstants);GRAPHQL</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Util\JsonUtilsTests.cs" />
|
<Compile Remove="Util\JsonUtilsTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -67,8 +63,11 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
||||||
<PackageReference Include="Moq" Version="4.17.2" />
|
<PackageReference Include="Moq" Version="4.17.2" />
|
||||||
|
|
||||||
|
<!--<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.1" />-->
|
||||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||||
<PackageReference Include="RestEase" Version="1.5.7" />
|
<PackageReference Include="RestEase" Version="1.5.7" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||||
<PackageReference Include="NFluent" Version="2.8.0" />
|
<PackageReference Include="NFluent" Version="2.8.0" />
|
||||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||||
<PackageReference Include="AnyOf" Version="0.3.0" />
|
<PackageReference Include="AnyOf" Version="0.3.0" />
|
||||||
@@ -105,10 +104,10 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Update="OpenApiParser\*.json">
|
<None Update="OpenApiParser\*.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="OpenApiParser\*.yml">
|
<None Update="OpenApiParser\*.yml">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="responsebody.json">
|
<None Update="responsebody.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
|||||||
@@ -1,210 +1,215 @@
|
|||||||
|
using Moq;
|
||||||
|
using NFluent;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using FluentAssertions;
|
|
||||||
using Moq;
|
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace WireMock.Net.Tests;
|
namespace WireMock.Net.Tests
|
||||||
|
|
||||||
public class WireMockServerAdminFilesTests
|
|
||||||
{
|
{
|
||||||
private readonly HttpClient _client = new HttpClient();
|
public class WireMockServerAdminFilesTests
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task WireMockServer_Admin_Files_Post_Ascii()
|
|
||||||
{
|
{
|
||||||
// Arrange
|
private readonly HttpClient _client = new HttpClient();
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("__admin/mappings");
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(true);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
|
||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
[Fact]
|
||||||
|
public async Task WireMockServer_Admin_Files_Post_Ascii()
|
||||||
{
|
{
|
||||||
UseSSL = false,
|
// Arrange
|
||||||
StartAdminInterface = true,
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
FileSystemHandler = filesystemHandlerMock.Object
|
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("__admin/mappings");
|
||||||
});
|
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(true);
|
||||||
|
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
||||||
|
|
||||||
var multipartFormDataContent = new MultipartFormDataContent();
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
{
|
||||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
UseSSL = false,
|
||||||
|
StartAdminInterface = true,
|
||||||
|
FileSystemHandler = filesystemHandlerMock.Object
|
||||||
|
});
|
||||||
|
|
||||||
// Act
|
var multipartFormDataContent = new MultipartFormDataContent();
|
||||||
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||||
|
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
||||||
|
|
||||||
// Assert
|
// Act
|
||||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.OK);
|
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
||||||
|
|
||||||
// Verify
|
// Assert
|
||||||
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.OK);
|
||||||
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
Check.That(server.LogEntries.Count().Equals(1));
|
||||||
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
|
||||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
// Verify
|
||||||
public async Task WireMockServer_Admin_Files_Post_MappingFolderDoesNotExistsButWillBeCreated()
|
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
||||||
{
|
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
||||||
// Arrange
|
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||||
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("x");
|
}
|
||||||
filesystemHandlerMock.Setup(fs => fs.CreateFolder(It.IsAny<string>()));
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(false);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
|
||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
[Fact]
|
||||||
|
public async Task WireMockServer_Admin_Files_Post_MappingFolderDoesNotExistsButWillBeCreated()
|
||||||
{
|
{
|
||||||
UseSSL = false,
|
// Arrange
|
||||||
StartAdminInterface = true,
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
FileSystemHandler = filesystemHandlerMock.Object
|
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("x");
|
||||||
});
|
filesystemHandlerMock.Setup(fs => fs.CreateFolder(It.IsAny<string>()));
|
||||||
|
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(false);
|
||||||
|
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
||||||
|
|
||||||
var multipartFormDataContent = new MultipartFormDataContent();
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
{
|
||||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
UseSSL = false,
|
||||||
|
StartAdminInterface = true,
|
||||||
|
FileSystemHandler = filesystemHandlerMock.Object
|
||||||
|
});
|
||||||
|
|
||||||
// Act
|
var multipartFormDataContent = new MultipartFormDataContent();
|
||||||
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||||
|
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
||||||
|
|
||||||
// Assert
|
// Act
|
||||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.OK);
|
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
||||||
|
|
||||||
// Verify
|
// Assert
|
||||||
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.OK);
|
||||||
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
|
||||||
filesystemHandlerMock.Verify(fs => fs.CreateFolder(It.Is<string>(p => p == "x")), Times.Once);
|
|
||||||
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
|
||||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
// Verify
|
||||||
public async Task WireMockServer_Admin_Files_GetAscii()
|
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
||||||
{
|
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
||||||
// Arrange
|
filesystemHandlerMock.Verify(fs => fs.CreateFolder(It.Is<string>(p => p == "x")), Times.Once);
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
||||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||||
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(Encoding.ASCII.GetBytes("Here's a string."));
|
}
|
||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
[Fact]
|
||||||
|
public async Task WireMockServer_Admin_Files_GetAscii()
|
||||||
{
|
{
|
||||||
UseSSL = false,
|
// Arrange
|
||||||
StartAdminInterface = true,
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
FileSystemHandler = filesystemHandlerMock.Object
|
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||||
});
|
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(Encoding.ASCII.GetBytes("Here's a string."));
|
||||||
|
|
||||||
var multipartFormDataContent = new MultipartFormDataContent();
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
{
|
||||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
UseSSL = false,
|
||||||
|
StartAdminInterface = true,
|
||||||
|
FileSystemHandler = filesystemHandlerMock.Object
|
||||||
|
});
|
||||||
|
|
||||||
// Act
|
var multipartFormDataContent = new MultipartFormDataContent();
|
||||||
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt").ConfigureAwait(false);
|
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||||
|
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
||||||
|
|
||||||
// Assert
|
// Act
|
||||||
httpResponseMessageGet.StatusCode.Should().Be(HttpStatusCode.OK);
|
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt").ConfigureAwait(false);
|
||||||
|
|
||||||
var result = await httpResponseMessageGet.Content.ReadAsStringAsync().ConfigureAwait(false);
|
// Assert
|
||||||
result.Should().Be("Here's a string.");
|
Check.That(httpResponseMessageGet.StatusCode).Equals(HttpStatusCode.OK);
|
||||||
|
|
||||||
// Verify
|
Check.That(httpResponseMessageGet.Content.ReadAsStringAsync().Result).Equals("Here's a string.");
|
||||||
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
|
||||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
|
||||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
Check.That(server.LogEntries.Count().Equals(2));
|
||||||
public async Task WireMockServer_Admin_Files_GetUTF16()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
byte[] symbol = Encoding.UTF32.GetBytes(char.ConvertFromUtf32(0x1D161));
|
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(symbol);
|
|
||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
// Verify
|
||||||
|
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
||||||
|
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
||||||
|
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WireMockServer_Admin_Files_GetUTF16()
|
||||||
{
|
{
|
||||||
UseSSL = false,
|
// Arrange
|
||||||
StartAdminInterface = true,
|
byte[] symbol = Encoding.UTF32.GetBytes(char.ConvertFromUtf32(0x1D161));
|
||||||
FileSystemHandler = filesystemHandlerMock.Object
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
});
|
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||||
|
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(symbol);
|
||||||
|
|
||||||
var multipartFormDataContent = new MultipartFormDataContent();
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
{
|
||||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
UseSSL = false,
|
||||||
|
StartAdminInterface = true,
|
||||||
|
FileSystemHandler = filesystemHandlerMock.Object
|
||||||
|
});
|
||||||
|
|
||||||
// Act
|
var multipartFormDataContent = new MultipartFormDataContent();
|
||||||
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.bin").ConfigureAwait(false);
|
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||||
|
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
||||||
|
|
||||||
// Assert
|
// Act
|
||||||
httpResponseMessageGet.StatusCode.Should().Be(HttpStatusCode.OK);
|
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.bin").ConfigureAwait(false);
|
||||||
|
|
||||||
var result = await httpResponseMessageGet.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
// Assert
|
||||||
result.Should().BeEquivalentTo(symbol);
|
Check.That(httpResponseMessageGet.StatusCode).Equals(HttpStatusCode.OK);
|
||||||
|
Check.That(httpResponseMessageGet.Content.ReadAsByteArrayAsync().Result).Equals(symbol);
|
||||||
|
Check.That(server.LogEntries.Count().Equals(2));
|
||||||
|
|
||||||
// Verify
|
// Verify
|
||||||
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
||||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
||||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockServer_Admin_Files_Head()
|
public async Task WireMockServer_Admin_Files_Head()
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
|
||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
|
||||||
{
|
{
|
||||||
UseSSL = false,
|
// Arrange
|
||||||
StartAdminInterface = true,
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
FileSystemHandler = filesystemHandlerMock.Object
|
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
{
|
||||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
UseSSL = false,
|
||||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
StartAdminInterface = true,
|
||||||
|
FileSystemHandler = filesystemHandlerMock.Object
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Act
|
||||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.NoContent);
|
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
||||||
|
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
||||||
|
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||||
|
|
||||||
// Verify
|
// Assert
|
||||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.NoContent);
|
||||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
Check.That(server.LogEntries.Count().Equals(1));
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
// Verify
|
||||||
public async Task WireMockServer_Admin_Files_Head_FileDoesNotExistsReturns404()
|
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
||||||
{
|
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||||
// Arrange
|
}
|
||||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
|
||||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(false);
|
|
||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
[Fact]
|
||||||
|
public async Task WireMockServer_Admin_Files_Head_FileDoesNotExistsReturns404()
|
||||||
{
|
{
|
||||||
UseSSL = false,
|
// Arrange
|
||||||
StartAdminInterface = true,
|
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||||
FileSystemHandler = filesystemHandlerMock.Object
|
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(false);
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
{
|
||||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
UseSSL = false,
|
||||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
StartAdminInterface = true,
|
||||||
|
FileSystemHandler = filesystemHandlerMock.Object
|
||||||
|
});
|
||||||
|
|
||||||
// Assert
|
// Act
|
||||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.NotFound);
|
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
||||||
|
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
||||||
|
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||||
|
|
||||||
// Verify
|
// Assert
|
||||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.NotFound);
|
||||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
Check.That(server.LogEntries.Count().Equals(1));
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
||||||
|
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user