Compare commits

...

19 Commits

Author SHA1 Message Date
Stef Heyenrath
09a302baf2 1.5.35 2023-08-19 10:00:18 +02:00
Stef Heyenrath
f0139eb837 Update comment in JsonPathMatcher.cs 2023-08-17 17:22:05 +02:00
DayLightDancer
8adf34fb56 Update JSONPathMatcher.cs to cover the string path selection to a child (#993)
* Update JSONPathMatcher.cs to cover the string path selection to a child 

The .SelectToken method accept string path selection and JSONPath queries. The current code works only for the queries because the result is JObject. When the string path is selected the result is JValue and event with a valid result the code the code doesn't return valued result.
https://www.newtonsoft.com/json/help/html/SelectToken.htm

* Added unit tests

* Addressed the comments

* Addressed the comments

* Update JSONPathMatcher.cs
2023-08-17 17:18:32 +02:00
Stef Heyenrath
fd816f0952 Add extra unit test for WithParam multiple values comma (#992) 2023-08-12 21:05:13 +02:00
Stef Heyenrath
205c1d598b 1.5.34 2023-08-04 10:51:51 +02:00
Stef Heyenrath
b986633eca Fix MimeKitLite NuGet include (#989)
* Fix 500

* MimeKiteLite : fix NuGet include

* .
2023-08-04 10:44:53 +02:00
Stef Heyenrath
6aa7aac151 1.5.33 2023-08-03 16:08:50 +02:00
Stef Heyenrath
4688f556b5 Add MultiPart/MimePart Request Matcher (#981)
* wip

* .

* mm

* x

* .

* .

* .

* tests

* .

* more tests

* trans

* x

* win

* fix

* .

* tests
2023-08-03 15:55:46 +02:00
Stef Heyenrath
a58ead7b4e Upgrade to Handlebars.Net.Helpers 2.4.0 to update XPath.SelectTokens and XPath.EvaluateToString (#976)
* Upgrade to Handlebars.Net.Helpers 2.4.0 to update XPath.SelectTokens and XPath.EvaluateToString

* fix
2023-07-20 21:49:00 +02:00
Tymur Nesterenko
58bfb3ea33 JsonPartialMatcher - match guid and string (#972)
* JsonPartialMatcher - match guid and string (#971)

* JsonPartialMatcher - match guid and string. Add Regex with Guid test (#971)
2023-07-19 22:34:02 +02:00
Stef Heyenrath
9c51548d2b 1.5.32 2023-07-15 09:41:05 +02:00
Stef Heyenrath
98b8ede826 Fixed JsonPathMatcher to match nested objects (#966)
* Fixed JsonPathMatcher to match nested objects

* fix

* .

* 100%
2023-07-15 09:29:13 +02:00
Stef Heyenrath
a6f3f976af 1.5.31 2023-07-08 14:57:12 +02:00
Stef Heyenrath
b495eb83b1 Add GraphQL Schema matching (#964)
* Add GrapQLMatcher

* tests

* x

* .

* .

* RequestMessageGraphQLMatcher

* .

* more tests

* tests

* ...

* ms

* .

* more tests

* GraphQL.NET !!!

* .

* executionResult

* nw

* sonarcloud
2023-07-07 21:43:46 +02:00
Stef Heyenrath
9443e4f071 1.5.30 2023-06-28 08:12:10 +02:00
dependabot[bot]
7a914481e5 Bump System.Linq.Dynamic.Core (#963)
Bumps [System.Linq.Dynamic.Core](https://github.com/zzzprojects/System.Linq.Dynamic.Core) from 1.2.23 to 1.3.0.
- [Release notes](https://github.com/zzzprojects/System.Linq.Dynamic.Core/releases)
- [Changelog](https://github.com/zzzprojects/System.Linq.Dynamic.Core/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zzzprojects/System.Linq.Dynamic.Core/compare/v1.2.23...v1.3.0)

---
updated-dependencies:
- dependency-name: System.Linq.Dynamic.Core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-28 07:58:03 +02:00
dependabot[bot]
1ad836659d Bump System.Linq.Dynamic.Core (#962)
Bumps [System.Linq.Dynamic.Core](https://github.com/zzzprojects/System.Linq.Dynamic.Core) from 1.2.23 to 1.3.0.
- [Release notes](https://github.com/zzzprojects/System.Linq.Dynamic.Core/releases)
- [Changelog](https://github.com/zzzprojects/System.Linq.Dynamic.Core/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zzzprojects/System.Linq.Dynamic.Core/compare/v1.2.23...v1.3.0)

---
updated-dependencies:
- dependency-name: System.Linq.Dynamic.Core
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-28 07:57:50 +02:00
Stef Heyenrath
ed7f9c1143 Add unit-test for Param - MatcherModel - LinqMatcher (#961) 2023-06-27 22:31:14 +02:00
Stef Heyenrath
c92183558b Fixed logic for FluentAssertions WithHeader (#959) 2023-06-23 15:20:57 +02:00
104 changed files with 3477 additions and 1100 deletions

View File

@@ -1,3 +1,35 @@
# 1.5.35 (19 August 2023)
- [#992](https://github.com/WireMock-Net/WireMock.Net/pull/992) - Add extra unit test for WithParam multiple values comma [test] contributed by [StefH](https://github.com/StefH)
- [#993](https://github.com/WireMock-Net/WireMock.Net/pull/993) - Update JSONPathMatcher.cs to cover the string path selection to a child contributed by [DayLightDancer](https://github.com/DayLightDancer)
# 1.5.34 (04 August 2023)
- [#989](https://github.com/WireMock-Net/WireMock.Net/pull/989) - Fix MimeKitLite NuGet include [bug] contributed by [StefH](https://github.com/StefH)
- [#988](https://github.com/WireMock-Net/WireMock.Net/issues/988) - v1.5.33 Returns always StatusCode 500 [bug]
# 1.5.33 (03 August 2023)
- [#972](https://github.com/WireMock-Net/WireMock.Net/pull/972) - JsonPartialMatcher - match guid and string contributed by [timurnes](https://github.com/timurnes)
- [#976](https://github.com/WireMock-Net/WireMock.Net/pull/976) - Upgrade to Handlebars.Net.Helpers 2.4.0 to update XPath.SelectTokens and XPath.EvaluateToString [feature] contributed by [StefH](https://github.com/StefH)
- [#981](https://github.com/WireMock-Net/WireMock.Net/pull/981) - Add MultiPart/MimePart Request Matcher [feature] contributed by [StefH](https://github.com/StefH)
- [#968](https://github.com/WireMock-Net/WireMock.Net/issues/968) - Using request multipart in response template [feature]
- [#969](https://github.com/WireMock-Net/WireMock.Net/issues/969) - Multipart validation [feature]
- [#970](https://github.com/WireMock-Net/WireMock.Net/issues/970) - Loop through xml elements in handlebars template [feature]
- [#971](https://github.com/WireMock-Net/WireMock.Net/issues/971) - JsonPartialMatcher - match guid and string [feature]
# 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) - &#11088;10 million downloads ! &#11088; [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)
@@ -955,7 +987,7 @@
- [#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)
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [vladimir-fed](https://github.com/vladimir-fed)
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [volodymyr-fed](https://github.com/volodymyr-fed)
- [#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.
@@ -982,7 +1014,7 @@
# 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)
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [vladimir-fed](https://github.com/vladimir-fed)
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [volodymyr-fed](https://github.com/volodymyr-fed)
- [#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]
- [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.5.29</VersionPrefix>
<VersionPrefix>1.5.35</VersionPrefix>
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>

View File

@@ -1,6 +1,6 @@
rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.5.29
SET version=1.5.35
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%

View File

@@ -1,6 +1,5 @@
# 1.5.29 (22 June 2023)
- #954 Support setting WireMockServerSettings via Environment [feature]
- #955 Fix some SonarCloud issues [refactor]
- #953 How to use environment variable [feature]
# 1.5.35 (19 August 2023)
- #992 Add extra unit test for WithParam multiple values comma [test]
- #993 Update JSONPathMatcher.cs to cover the string path selection to a child
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -111,10 +111,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueExample",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMockAzureQueueProxy", "examples\WireMockAzureQueueProxy\WireMockAzureQueueProxy.csproj", "{ADB557D8-D66B-4387-912B-3F73E290B478}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Testcontainers", "src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj", "{12B016A5-9D8B-4EFE-96C2-CA51BE43367D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{0147029F-FA4A-44B3-B79A-3C3574054EE4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultipartUploader", "tools\MultipartUploader\MultipartUploader.csproj", "{07C30227-ADEC-4BDE-8CDC-849D85A690BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.NET7.UsingNuGet", "examples\WireMock.Net.Console.NET7.UsingNuGet\WireMock.Net.Console.NET7.UsingNuGet.csproj", "{941229D6-191B-4B5E-AC81-0905EBF4F19D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -277,6 +283,14 @@ Global
{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
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07C30227-ADEC-4BDE-8CDC-849D85A690BB}.Release|Any CPU.Build.0 = Release|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{941229D6-191B-4B5E-AC81-0905EBF4F19D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -323,6 +337,8 @@ Global
{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}
{07C30227-ADEC-4BDE-8CDC-849D85A690BB} = {0147029F-FA4A-44B3-B79A-3C3574054EE4}
{941229D6-191B-4B5E-AC81-0905EBF4F19D} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}

View File

@@ -14,6 +14,7 @@
<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/=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/=SSL/@EntryIndexedValue">SSL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String>

View File

@@ -73,7 +73,6 @@ class Program
var settingsViaBuilder = new SettingsModelBuilder()
.WithGlobalProcessingDelay(1077)
.WithoutGlobalProcessingDelay()
.Build();
settings1.GlobalProcessingDelay = 1077;

View File

@@ -28,10 +28,10 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -3,6 +3,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup>
@@ -27,10 +28,8 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<!--<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />-->
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,34 @@
using System.Net;
using System.Text;
using FluentAssertions;
using WireMock.Logging;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using WireMock.Settings;
namespace WireMock.Net.Console.NET7.UsingNuGet;
internal class Program
{
private static async Task Main(string[] args)
{
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = new WireMockConsoleLogger(),
});
server.Given(Request.Create().UsingPost().WithPath("/some/endpoint"))
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.Created));
var httpClient = new HttpClient { BaseAddress = new Uri(server.Url!) };
var requestUri = new Uri(httpClient.BaseAddress!, "some/endpoint");
var content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
// Act
var actual = await httpClient.PostAsync(requestUri, content);
// Assert
actual.StatusCode.Should().Be(HttpStatusCode.Created);
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="WireMock.Net" Version="1.5.32" />
</ItemGroup>
</Project>

View File

@@ -19,14 +19,14 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -31,14 +31,14 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -28,14 +28,14 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.*" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.*" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -42,6 +42,36 @@ namespace WireMock.Net.ConsoleApplication
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()
{
var mappingBuilder = new MappingBuilder();
@@ -136,7 +166,51 @@ namespace WireMock.Net.ConsoleApplication
//server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef");
// server.AllowPartialMapping();
#if GRAPHQL
server
.Given(Request.Create()
.WithPath("/graphql")
.UsingPost()
.WithGraphQLSchema(TestSchema)
)
.RespondWith(Response.Create()
.WithBody("GraphQL is ok")
);
#endif
#if MIMEKIT
var textPlainContentTypeMatcher = new ContentTypeMatcher("text/plain");
var textPlainContentMatcher = new ExactMatcher("This is some plain text");
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
var textJsonContentTypeMatcher = new ContentTypeMatcher("text/json");
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var textJsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
var imagePngContentTypeMatcher = new ContentTypeMatcher("image/png");
var imagePngContentDispositionMatcher = new ExactMatcher("attachment; filename=\"image.png\"");
var imagePngContentTransferEncodingMatcher = new ExactMatcher("base64");
var imagePngContentMatcher = new ExactObjectMatcher(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"));
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, imagePngContentTypeMatcher, imagePngContentDispositionMatcher, imagePngContentTransferEncodingMatcher, imagePngContentMatcher);
var matchers = new IMatcher[]
{
textPlainMatcher,
textJsonMatcher,
imagePngMatcher
};
server
.Given(Request.Create()
.WithPath("/multipart")
.UsingPost()
.WithMultiPart(matchers)
)
.WithGuid("b9c82182-e469-41da-bcaf-b6e3157fefdb")
.RespondWith(Response.Create()
.WithBody("MultiPart is ok")
);
#endif
// 400 ms
server
.Given(Request.Create()
@@ -676,8 +750,9 @@ namespace WireMock.Net.ConsoleApplication
}));
server.Given(Request.Create().WithPath(new WildcardMatcher("/multi-webhook", true)).UsingPost())
.WithWebhook(new[] {
new Webhook()
.WithWebhook
(
new Webhook
{
Request = new WebhookRequest
{
@@ -685,12 +760,13 @@ namespace WireMock.Net.ConsoleApplication
Method = "post",
BodyData = new BodyData
{
BodyAsString = "OK 1!", DetectedBodyType = BodyType.String
BodyAsString = "OK 1!",
DetectedBodyType = BodyType.String
},
Delay = 1000
}
},
new Webhook()
new Webhook
{
Request = new WebhookRequest
{
@@ -705,7 +781,7 @@ namespace WireMock.Net.ConsoleApplication
MaximumRandomDelay = 7000
}
}
})
)
.WithWebhookFireAndForget(true)
.RespondWith(Response.Create().WithBody("a-response"));

View File

@@ -39,14 +39,14 @@
<Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL">
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
</Reference>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net452\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net452\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net452\Handlebars.Net.Helpers.dll</HintPath>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net452\Handlebars.Net.Helpers.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
@@ -56,7 +56,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>
@@ -67,6 +67,7 @@
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Net.Http" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
</Reference>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AnyOf" version="0.3.0" targetFramework="net452" />
<package id="Handlebars.Net" version="2.1.2" targetFramework="net452" />
<package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net452" />
<package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net452" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net452" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net452" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net452" />
<package id="log4net" version="2.0.15" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
<package id="Stef.Validation" version="0.1.1" targetFramework="net452" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net452" />

View File

@@ -38,14 +38,14 @@
<Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL">
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
</Reference>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
@@ -54,7 +54,7 @@
<HintPath>..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AnyOf" version="0.3.0" targetFramework="net461" />
<package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
<package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net461" />
<package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net461" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net461" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net461" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net461" />
<package id="log4net" version="2.0.15" targetFramework="net461" />
<package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="2.2.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net461" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
<package id="Stef.Validation" version="0.1.1" targetFramework="net461" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net461" />

View File

@@ -101,6 +101,10 @@
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.25.0.0" newVersion="6.25.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="NJsonSchema" publicKeyToken="c2f9c3bdfae56102" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.7.2.0" newVersion="10.7.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@@ -46,32 +46,32 @@
<Reference Include="Fare, Version=2.2.0.0, Culture=neutral, PublicKeyToken=ea68d375bf33a7c8, processorArchitecture=MSIL">
<HintPath>..\..\packages\Fare.2.2.1\lib\net35\Fare.dll</HintPath>
</Reference>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Handlebars.Net.Helpers, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.3.12\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
<Reference Include="Handlebars.Net.Helpers, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.0\lib\net46\Handlebars.Net.Helpers.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Core.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.3.12\lib\net46\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.DynamicLinq, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.DynamicLinq.2.4.0\lib\net46\HandlebarsDotNet.Helpers.DynamicLinq.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Humanizer, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Humanizer.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Humanizer.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Json.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Json, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Json.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Json.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Random.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Random, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Random.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Random.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.3.12\lib\net46\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.Xeger, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.Xeger.2.4.0\lib\net46\HandlebarsDotNet.Helpers.Xeger.dll</HintPath>
</Reference>
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.3.12.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.3.12\lib\net46\HandlebarsDotNet.Helpers.XPath.dll</HintPath>
<Reference Include="HandlebarsDotNet.Helpers.XPath, Version=2.4.0.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.Helpers.XPath.2.4.0\lib\net46\HandlebarsDotNet.Helpers.XPath.dll</HintPath>
</Reference>
<Reference Include="Humanizer, Version=2.14.0.0, Culture=neutral, PublicKeyToken=979442b78dfc278e, processorArchitecture=MSIL">
<HintPath>..\..\packages\Humanizer.Core.2.14.1\lib\netstandard2.0\Humanizer.dll</HintPath>
@@ -257,16 +257,16 @@
<HintPath>..\..\packages\Namotion.Reflection.2.0.10\lib\net45\Namotion.Reflection.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NJsonSchema, Version=10.6.10.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.10.6.10\lib\net45\NJsonSchema.dll</HintPath>
<Reference Include="NJsonSchema, Version=10.7.2.0, Culture=neutral, PublicKeyToken=c2f9c3bdfae56102, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.10.7.2\lib\net45\NJsonSchema.dll</HintPath>
</Reference>
<Reference Include="NJsonSchema.Extensions, Version=0.1.0.0, Culture=neutral, PublicKeyToken=e52fadf300daf456, processorArchitecture=MSIL">
<HintPath>..\..\packages\NJsonSchema.Extensions.0.1.0\lib\net45\NJsonSchema.Extensions.dll</HintPath>
</Reference>
<Reference Include="NSwag.Core, Version=13.15.10.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL">
<HintPath>..\..\packages\NSwag.Core.13.15.10\lib\net45\NSwag.Core.dll</HintPath>
<Reference Include="NSwag.Core, Version=13.16.1.0, Culture=neutral, PublicKeyToken=c2d88086e098d109, processorArchitecture=MSIL">
<HintPath>..\..\packages\NSwag.Core.13.16.1\lib\net45\NSwag.Core.dll</HintPath>
</Reference>
<Reference Include="RandomDataGenerator, Version=1.0.16.0, Culture=neutral, PublicKeyToken=ae5c571d29a3b8d9, processorArchitecture=MSIL">
<HintPath>..\..\packages\RandomDataGenerator.Net.1.0.17\lib\net45\RandomDataGenerator.dll</HintPath>
@@ -302,8 +302,8 @@
<Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Linq.Dynamic.Core, Version=1.2.23.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.2.23\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
<Reference Include="System.Linq.Dynamic.Core, Version=1.3.1.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.1\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>

View File

@@ -2,15 +2,15 @@
<packages>
<package id="AnyOf" version="0.3.0" targetFramework="net472" />
<package id="Fare" version="2.2.1" targetFramework="net472" />
<package id="Handlebars.Net" version="2.1.2" targetFramework="net472" />
<package id="Handlebars.Net.Helpers" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Core" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Humanizer" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Json" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Random" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Xeger" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.XPath" version="2.3.12" targetFramework="net472" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net472" />
<package id="Handlebars.Net.Helpers" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Core" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.DynamicLinq" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Humanizer" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Json" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Random" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.Xeger" version="2.4.0" targetFramework="net472" />
<package id="Handlebars.Net.Helpers.XPath" version="2.4.0" targetFramework="net472" />
<package id="Humanizer" version="2.14.1" targetFramework="net472" />
<package id="Humanizer.Core" version="2.14.1" targetFramework="net472" />
<package id="Humanizer.Core.af" version="2.14.1" targetFramework="net472" />
@@ -123,10 +123,10 @@
<package id="Microsoft.IdentityModel.Tokens" version="6.25.0" targetFramework="net472" />
<package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net472" />
<package id="Namotion.Reflection" version="2.0.10" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
<package id="NJsonSchema" version="10.6.10" targetFramework="net472" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net472" />
<package id="NJsonSchema" version="10.7.2" targetFramework="net472" />
<package id="NJsonSchema.Extensions" version="0.1.0" targetFramework="net472" />
<package id="NSwag.Core" version="13.15.10" targetFramework="net472" />
<package id="NSwag.Core" version="13.16.1" targetFramework="net472" />
<package id="Nullable" version="1.3.1" targetFramework="net472" developmentDependency="true" />
<package id="RandomDataGenerator.Net" version="1.0.17" targetFramework="net472" />
<package id="Scriban.Signed" version="2.1.4" targetFramework="net472" />
@@ -138,7 +138,7 @@
<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.IO.Pipelines" version="4.5.3" targetFramework="net472" />
<package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net472" />
<package id="System.Linq.Dynamic.Core" version="1.3.1" 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.Reflection.Metadata" version="1.6.0" targetFramework="net472" />

View File

@@ -9,7 +9,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -7,7 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -72,7 +72,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" />
</packages>

View File

@@ -46,7 +46,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>

View File

@@ -8,7 +8,7 @@
<package id="Microsoft.Owin" version="4.2.2" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net452" />
<package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
<package id="Owin" version="1.0" targetFramework="net452" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
<package id="System.Net.Http" version="4.3.4" targetFramework="net452" requireReinstallation="true" />

View File

@@ -13,7 +13,7 @@ public class Program
{
XmlConfigurator.Configure(new FileInfo("log4net.config"));
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings))
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings))
{
Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));

View File

@@ -46,7 +46,7 @@
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />

View File

@@ -3,5 +3,5 @@
<package id="log4net" version="2.0.15" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.6" targetFramework="net452" />
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.0" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" />
</packages>

View File

@@ -9,7 +9,7 @@ static class Program
{
static void Main(string[] args)
{
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings))
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings))
{
Console.WriteLine("WireMock.Net server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));

View File

@@ -39,8 +39,8 @@
<StartupObject>WireMock.Net.StandAlone.Net461.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="Handlebars, Version=2.1.2.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.2\lib\net46\Handlebars.dll</HintPath>
<Reference Include="Handlebars, Version=2.1.4.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
<HintPath>..\..\packages\Handlebars.Net.2.1.4\lib\net46\Handlebars.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNetCore, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNetCore.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.dll</HintPath>
@@ -205,7 +205,7 @@
<HintPath>..\..\packages\MimeKitLite.2.0.7\lib\net45\MimeKitLite.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
@@ -235,8 +235,8 @@
<Reference Include="System.IO.Pipelines, Version=4.0.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Pipelines.4.5.3\lib\netstandard2.0\System.IO.Pipelines.dll</HintPath>
</Reference>
<Reference Include="System.Linq.Dynamic.Core, Version=1.2.23.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.2.23\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
<Reference Include="System.Linq.Dynamic.Core, Version=1.3.1.0, Culture=neutral, PublicKeyToken=0f07ec44de6ac832, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Linq.Dynamic.Core.1.3.1\lib\net46\System.Linq.Dynamic.Core.dll</HintPath>
</Reference>
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
<package id="Handlebars.Net" version="2.1.4" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.9" targetFramework="net461" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.9" targetFramework="net461" />
@@ -59,7 +59,7 @@
<package id="Microsoft.Owin.Host.HttpListener" version="4.2.2" targetFramework="net461" />
<package id="Microsoft.Owin.Hosting" version="4.2.2" targetFramework="net461" />
<package id="MimeKitLite" version="2.0.7" targetFramework="net461" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net461" />
<package id="Owin" version="1.0" targetFramework="net461" />
<package id="RestEase" version="1.5.7" targetFramework="net461" />
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
@@ -68,7 +68,7 @@
<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.IO.Pipelines" version="4.5.3" targetFramework="net461" />
<package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net461" />
<package id="System.Linq.Dynamic.Core" version="1.3.1" 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.Reflection.Metadata" version="1.6.0" targetFramework="net461" />

View File

@@ -12,7 +12,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,13 +12,13 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0'">
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1'">
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.4" />
<PackageReference Include="Microsoft.AspNetCore.All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,7 +12,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -39,14 +39,38 @@ public class MatcherModel
/// <summary>
/// The Operator to use when multiple patterns are defined. Optional.
/// - null = Same as "or".
/// - "or" = Only one pattern should match.
/// - "or" = Only one pattern is required to match.
/// - "and" = All patterns should match.
/// - "average" = The average value from all patterns.
/// </summary>
public string? MatchOperator { get; set; }
#region JsonPartialMatcher and JsonPartialWildcardMatcher
/// <summary>
/// Support Regex, only used for JsonPartialMatcher.
/// Support Regex.
/// </summary>
public bool? Regex { get; set; }
#endregion
#region MimePartMatcher
/// <summary>
/// ContentType Matcher (image/png; name=image.png)
/// </summary>
public MatcherModel? ContentTypeMatcher { get; set; }
/// <summary>
/// ContentDisposition Matcher (attachment; filename=image.png)
/// </summary>
public MatcherModel? ContentDispositionMatcher { get; set; }
/// <summary>
/// ContentTransferEncoding Matcher (base64)
/// </summary>
public MatcherModel? ContentTransferEncodingMatcher { get; set; }
/// <summary>
/// Content Matcher
/// </summary>
public MatcherModel? ContentMatcher { get; set; }
#endregion
}

View File

@@ -96,32 +96,39 @@ public interface IRequestMessage
/// <summary>
/// The original body as string. Convenience getter for Handlebars.
/// </summary>
string Body { get; }
string? Body { get; }
/// <summary>
/// The body (as JSON object). Convenience getter for Handlebars.
/// </summary>
object BodyAsJson { get; }
object? BodyAsJson { get; }
/// <summary>
/// The body (as bytearray). Convenience getter for Handlebars.
/// </summary>
byte[] BodyAsBytes { get; }
byte[]? BodyAsBytes { get; }
#if MIMEKIT
/// <summary>
/// The original body as MimeMessage. Convenience getter for Handlebars.
/// </summary>
object? BodyAsMimeMessage { get; }
#endif
/// <summary>
/// The detected body type. Convenience getter for Handlebars.
/// </summary>
string DetectedBodyType { get; }
string? DetectedBodyType { get; }
/// <summary>
/// The detected body type from the Content-Type header. Convenience getter for Handlebars.
/// </summary>
string DetectedBodyTypeFromContentType { get; }
string? DetectedBodyTypeFromContentType { get; }
/// <summary>
/// The detected compression from the Content-Encoding header. Convenience getter for Handlebars.
/// </summary>
string DetectedCompression { get; }
string? DetectedCompression { get; }
/// <summary>
/// Gets the Host

View File

@@ -30,6 +30,10 @@
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1'" >
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />

View File

@@ -149,15 +149,15 @@ public class WireMockAssertions
using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)"))
{
var headerValues = _headers.First(h => h.Key == expectedKey).Value;
var matchingHeaderValues = _headers.Where(h => h.Key == expectedKey).SelectMany(h => h.Value.ToArray()).ToArray();
if (expectedValues.Length == 1)
{
headerValues.Should().Contain(expectedValues.First(), because, becauseArgs);
matchingHeaderValues.Should().Contain(expectedValues.First(), because, becauseArgs);
}
else
{
var trimmedHeaderValues = string.Join(",", headerValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
var trimmedHeaderValues = string.Join(",", matchingHeaderValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
foreach (var expectedValue in expectedValues)
{
trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs);

View File

@@ -20,7 +20,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.2.3" />
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>

View File

@@ -26,7 +26,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Stef.Validation" Version="0.1.1" />
<PackageReference Include="xUnit.abstractions" Version="2.0.3" />
</ItemGroup>

View File

@@ -31,21 +31,14 @@ internal static class HttpRequestMessageHelper
MediaTypeHeaderValue.TryParse(value, out contentType);
}
switch (requestMessage.BodyData?.DetectedBodyType)
httpRequestMessage.Content = requestMessage.BodyData?.DetectedBodyType switch
{
case BodyType.Bytes:
httpRequestMessage.Content = ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType);
break;
case BodyType.Json:
httpRequestMessage.Content = StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType);
break;
case BodyType.String:
case BodyType.FormUrlEncoded:
httpRequestMessage.Content = StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType);
break;
}
BodyType.Bytes => ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType),
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType),
BodyType.String => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
BodyType.FormUrlEncoded => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
_ => httpRequestMessage.Content
};
// Overwrite the host header
httpRequestMessage.Headers.Host = new Uri(url).Authority;

View File

@@ -74,6 +74,13 @@ public abstract class AbstractJsonPartialMatcher : JsonMatcher
}
}
if (input != null &&
((value.Type == JTokenType.Guid && input.Type == JTokenType.String) ||
(value.Type == JTokenType.String && input.Type == JTokenType.Guid)))
{
return IsMatch(value.ToString(), input.ToString());
}
if (input == null || value.Type != input.Type)
{
return false;

View File

@@ -0,0 +1,139 @@
#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 />
public string Name => nameof(GraphQLMatcher);
private static ISchema BuildSchema(string schema)
{
return Schema.For(schema);
}
}
#endif

View File

@@ -0,0 +1,78 @@
using Stef.Validation;
using WireMock.Types;
using WireMock.Util;
namespace WireMock.Matchers.Helpers;
internal static class BodyDataMatchScoreCalculator
{
public static double CalculateMatchScore(IBodyData? requestMessage, IMatcher matcher)
{
Guard.NotNull(matcher);
if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
{
switch (requestMessage?.DetectedBodyType)
{
case BodyType.Json:
case BodyType.String:
case BodyType.FormUrlEncoded:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsString);
case BodyType.Bytes:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyAsBytes);
default:
return MatchScores.Mismatch;
}
}
if (matcher is ExactObjectMatcher exactObjectMatcher)
{
// If the body is a byte array, try to match.
var detectedBodyType = requestMessage?.DetectedBodyType;
if (detectedBodyType is BodyType.Bytes or BodyType.String or BodyType.FormUrlEncoded)
{
return exactObjectMatcher.IsMatch(requestMessage?.BodyAsBytes);
}
}
// Check if the matcher is a IObjectMatcher
if (matcher is IObjectMatcher objectMatcher)
{
// If the body is a JSON object, try to match.
if (requestMessage?.DetectedBodyType == BodyType.Json)
{
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
}
// If the body is a byte array, try to match.
if (requestMessage?.DetectedBodyType == BodyType.Bytes)
{
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
}
}
// Check if the matcher is a IStringMatcher
if (matcher is IStringMatcher stringMatcher)
{
// If the body is a Json or a String, use the BodyAsString to match on.
if (requestMessage?.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
{
return stringMatcher.IsMatch(requestMessage.BodyAsString);
}
}
#if MIMEKIT_XXX
if (matcher is MultiPartMatcher multiPartMatcher)
{
// If the body is a String or MultiPart, use the BodyAsString to match on.
if (requestMessage?.DetectedBodyType is BodyType.String or BodyType.MultiPart)
{
return multiPartMatcher.IsMatch(requestMessage.BodyAsString);
}
}
#endif
return MatchScores.Mismatch;
}
}

View File

@@ -121,6 +121,34 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
private double IsMatch(JToken jToken)
{
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
var array = ConvertJTokenToJArrayIfNeeded(jToken);
// The SelectToken method can accept a string path to a child token ( i.e. "Manufacturers[0].Products[0].Price").
// In that case it will return a JValue (some type) which does not implement the IEnumerable interface.
return MatchScores.ToScore(_patterns.Select(pattern => array.SelectToken(pattern.GetPattern()) != null).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;
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using AnyOfTypes;
@@ -69,7 +68,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
MatchOperator = matchOperator;
}
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
/// <inheritdoc />
public double IsMatch(string? input)
{
double match = MatchScores.Mismatch;
@@ -95,7 +94,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
/// <inheritdoc />
public double IsMatch(object? input)
{
double match = MatchScores.Mismatch;
@@ -110,45 +109,19 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
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.
//var queryable1 = new[] { value }.AsQueryable();
var queryable = jArray.ToDynamicClassArray().AsQueryable();
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 scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray();
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
match = MatchScores.ToScore(scores, MatchOperator);
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
catch (Exception e)
catch
{
if (ThrowException)
{
@@ -159,7 +132,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
/// <inheritdoc />
public AnyOf<string, StringPattern>[] GetPatterns()
{
return _patterns;
@@ -168,6 +141,6 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// <inheritdoc />
public MatchOperator MatchOperator { get; }
/// <inheritdoc cref="IMatcher.Name"/>
/// <inheritdoc />
public string Name => "LinqMatcher";
}

View File

@@ -1,7 +1,7 @@
namespace WireMock.Matchers;
/// <summary>
/// MatchBehaviour
/// MatchBehaviour (Accept or Reject)
/// </summary>
public enum MatchBehaviour
{

View File

@@ -0,0 +1,125 @@
#if MIMEKIT
using System;
using MimeKit;
using WireMock.Matchers.Helpers;
using WireMock.Util;
namespace WireMock.Matchers;
/// <summary>
/// MimePartMatcher
/// </summary>
public class MimePartMatcher : IMatcher
{
private readonly Func<MimePart, double>[] _funcs;
/// <inheritdoc />
public string Name => nameof(MimePartMatcher);
/// <summary>
/// ContentType Matcher (image/png; name=image.png.)
/// </summary>
public IStringMatcher? ContentTypeMatcher { get; }
/// <summary>
/// ContentDisposition Matcher (attachment; filename=image.png)
/// </summary>
public IStringMatcher? ContentDispositionMatcher { get; }
/// <summary>
/// ContentTransferEncoding Matcher (base64)
/// </summary>
public IStringMatcher? ContentTransferEncodingMatcher { get; }
/// <summary>
/// Content Matcher
/// </summary>
public IMatcher? ContentMatcher { get; }
/// <inheritdoc />
public MatchBehaviour MatchBehaviour { get; }
/// <inheritdoc />
public bool ThrowException { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MimePartMatcher"/> class.
/// </summary>
public MimePartMatcher(
MatchBehaviour matchBehaviour,
IStringMatcher? contentTypeMatcher,
IStringMatcher? contentDispositionMatcher,
IStringMatcher? contentTransferEncodingMatcher,
IMatcher? contentMatcher,
bool throwException = false
)
{
MatchBehaviour = matchBehaviour;
ContentTypeMatcher = contentTypeMatcher;
ContentDispositionMatcher = contentDispositionMatcher;
ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
ContentMatcher = contentMatcher;
ThrowException = throwException;
_funcs = new[]
{
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect,
MatchOnContent
};
}
/// <summary>
/// Determines whether the specified MimePart is match.
/// </summary>
/// <param name="mimePart">The MimePart.</param>
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
public double IsMatch(MimePart mimePart)
{
var match = MatchScores.Mismatch;
try
{
if (Array.TrueForAll(_funcs, func => MatchScores.IsPerfect(func(mimePart))))
{
match = MatchScores.Perfect;
}
}
catch
{
if (ThrowException)
{
throw;
}
}
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
}
private double MatchOnContent(MimePart mimePart)
{
if (ContentMatcher == null)
{
return MatchScores.Perfect;
}
var bodyParserSettings = new BodyParserSettings
{
Stream = mimePart.Content.Open(),
ContentType = GetContentTypeAsString(mimePart.ContentType),
DeserializeJson = true,
ContentEncoding = null, // mimePart.ContentType.CharsetEncoding.ToString(),
DecompressGZipAndDeflate = true
};
var bodyData = BodyParser.ParseAsync(bodyParserSettings).ConfigureAwait(false).GetAwaiter().GetResult();
return BodyDataMatchScoreCalculator.CalculateMatchScore(bodyData, ContentMatcher);
}
private static string? GetContentTypeAsString(ContentType? contentType)
{
return contentType?.ToString().Replace("Content-Type: ", string.Empty);
}
}
#endif

View File

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Stef.Validation;
using WireMock.Types;
using WireMock.Matchers.Helpers;
using WireMock.Util;
namespace WireMock.Matchers.Request;
@@ -149,69 +149,11 @@ public class RequestMessageBodyMatcher : IRequestMatcher
return requestMatchResult.AddScore(GetType(), score);
}
private static double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
{
if (matcher is NotNullOrEmptyMatcher notNullOrEmptyMatcher)
{
switch (requestMessage.BodyData?.DetectedBodyType)
{
case BodyType.Json:
case BodyType.String:
case BodyType.FormUrlEncoded:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
case BodyType.Bytes:
return notNullOrEmptyMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
default:
return MatchScores.Mismatch;
}
}
if (matcher is ExactObjectMatcher exactObjectMatcher)
{
// If the body is a byte array, try to match.
var detectedBodyType = requestMessage.BodyData?.DetectedBodyType;
if (detectedBodyType is BodyType.Bytes or BodyType.String or BodyType.FormUrlEncoded)
{
return exactObjectMatcher.IsMatch(requestMessage.BodyData?.BodyAsBytes);
}
}
// Check if the matcher is a IObjectMatcher
if (matcher is IObjectMatcher objectMatcher)
{
// If the body is a JSON object, try to match.
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
{
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson);
}
// If the body is a byte array, try to match.
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes)
{
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
}
}
// Check if the matcher is a IStringMatcher
if (matcher is IStringMatcher stringMatcher)
{
// If the body is a Json or a String, use the BodyAsString to match on.
if (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)
{
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
var matchersResult = Matchers.Select(matcher => BodyDataMatchScoreCalculator.CalculateMatchScore(requestMessage.BodyData, matcher)).ToArray();
return MatchScores.ToScore(matchersResult, MatchOperator);
}

View File

@@ -0,0 +1,105 @@
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
}

View File

@@ -0,0 +1,99 @@
using System.Collections.Generic;
using System.Linq;
using Stef.Validation;
using WireMock.Http;
using WireMock.Util;
namespace WireMock.Matchers.Request;
/// <summary>
/// The request body MultiPart matcher.
/// </summary>
public class RequestMessageMultiPartMatcher : IRequestMatcher
{
/// <summary>
/// The matchers.
/// </summary>
public IMatcher[]? Matchers { get; }
/// <summary>
/// The <see cref="MatchOperator"/>
/// </summary>
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
/// <summary>
/// The <see cref="MatchBehaviour"/>
/// </summary>
public MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageMultiPartMatcher"/> class.
/// </summary>
/// <param name="matchers">The matchers.</param>
public RequestMessageMultiPartMatcher(params IMatcher[] matchers)
{
Matchers = Guard.NotNull(matchers);
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageMultiPartMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageMultiPartMatcher(MatchBehaviour matchBehaviour, MatchOperator matchOperator, params IMatcher[] matchers)
{
Matchers = Guard.NotNull(matchers);
MatchBehaviour = matchBehaviour;
MatchOperator = matchOperator;
}
/// <inheritdoc />
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
{
#if !MIMEKIT
throw new System.NotSupportedException("The MultiPartMatcher can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
#else
var match = MatchScores.Mismatch;
if (Matchers?.Any() != true)
{
return requestMatchResult.AddScore(GetType(), match);
}
try
{
var message = MimeKitUtils.GetMimeMessage(requestMessage.BodyData!, requestMessage.Headers![HttpKnownHeaderNames.ContentType].ToString());
var mimePartMatchers = Matchers.OfType<MimePartMatcher>().ToArray();
foreach (var mimePart in message.BodyParts.OfType<MimeKit.MimePart>())
{
var matchesForMimePart = new List<double> { MatchScores.Mismatch };
matchesForMimePart.AddRange(mimePartMatchers.Select(matcher => matcher.IsMatch(mimePart)));
match = matchesForMimePart.Max();
if (MatchScores.IsPerfect(match))
{
if (MatchOperator == MatchOperator.Or)
{
break;
}
}
else
{
match = MatchScores.Mismatch;
break;
}
}
}
catch
{
// Empty
}
return requestMatchResult.AddScore(GetType(), match);
#endif
}
}

View File

@@ -29,17 +29,13 @@ namespace WireMock.Owin.Mappers
var headers = new Dictionary<string, string[]>();
IEnumerable<string>? contentEncodingHeader = null;
if (request.Headers.Any())
foreach (var header in request.Headers)
{
headers = new Dictionary<string, string[]>();
foreach (var header in request.Headers)
{
headers.Add(header.Key, header.Value);
headers.Add(header.Key, header.Value!);
if (string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase))
{
contentEncodingHeader = header.Value;
}
if (string.Equals(header.Key, HttpKnownHeaderNames.ContentEncoding, StringComparison.OrdinalIgnoreCase))
{
contentEncodingHeader = header.Value;
}
}

View File

@@ -10,7 +10,7 @@ namespace WireMock.RequestBuilders;
/// <summary>
/// The BodyRequestBuilder interface.
/// </summary>
public interface IBodyRequestBuilder : IRequestMatcher
public interface IBodyRequestBuilder : IGraphQLRequestBuilder
{
/// <summary>
/// WithBody: IMatcher
@@ -103,4 +103,12 @@ public interface IBodyRequestBuilder : IRequestMatcher
/// <param name="func">The form-urlencoded values.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
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);
}

View File

@@ -0,0 +1,27 @@
using WireMock.Matchers;
namespace WireMock.RequestBuilders;
/// <summary>
/// The GraphQLRequestBuilder interface.
/// </summary>
public interface IGraphQLRequestBuilder : IMultiPartRequestBuilder
{
/// <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
}

View File

@@ -1,5 +1,3 @@
using System;
using JetBrains.Annotations;
using WireMock.Matchers;
namespace WireMock.RequestBuilders;

View File

@@ -0,0 +1,34 @@
using WireMock.Matchers;
using WireMock.Matchers.Request;
namespace WireMock.RequestBuilders;
/// <summary>
/// The MultiPartRequestBuilder interface.
/// </summary>
public interface IMultiPartRequestBuilder : IRequestMatcher
{
/// <summary>
/// WithMultiPart: IMatcher
/// </summary>
/// <param name="matcher">The matcher.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithMultiPart(IMatcher matcher);
/// <summary>
/// WithMultiPart: IMatcher[], MatchBehaviour and MatchOperator
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <param name="matchBehaviour">The <see cref="MatchBehaviour"/> to use.</param>
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithMultiPart(IMatcher[] matchers, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or);
/// <summary>
/// WithMultiPart: MatchBehaviour and IMatcher[]
/// </summary>
/// <param name="matchBehaviour">The <see cref="MatchBehaviour"/> to use.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithMultiPart(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, params IMatcher[] matchers);
}

View File

@@ -109,4 +109,10 @@ public partial class Request
_requestMatchers.Add(new RequestMessageBodyMatcher(Guard.NotNull(func)));
return this;
}
/// <inheritdoc />
public IRequestBuilder WithBodyAsGraphQLSchema(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return WithGraphQLSchema(body, matchBehaviour);
}
}

View File

@@ -0,0 +1,23 @@
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
}

View File

@@ -0,0 +1,28 @@
using WireMock.Matchers;
using WireMock.Matchers.Request;
namespace WireMock.RequestBuilders;
public partial class Request
{
/// <inheritdoc />
public IRequestBuilder WithMultiPart(IMatcher matcher)
{
_requestMatchers.Add(new RequestMessageMultiPartMatcher(matcher));
return this;
}
/// <inheritdoc />
public IRequestBuilder WithMultiPart(IMatcher[] matchers, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, MatchOperator matchOperator = MatchOperator.Or)
{
_requestMatchers.Add(new RequestMessageMultiPartMatcher(matchBehaviour, matchOperator, matchers));
return this;
}
/// <inheritdoc />
public IRequestBuilder WithMultiPart(MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, params IMatcher[] matchers)
{
_requestMatchers.Add(new RequestMessageMultiPartMatcher(matchBehaviour, MatchOperator.Or, matchers));
return this;
}
}

View File

@@ -8,6 +8,7 @@ using System.Net;
using System.Security.Cryptography.X509Certificates;
#endif
using Stef.Validation;
using WireMock.Http;
using WireMock.Models;
using WireMock.Owin;
using WireMock.Types;
@@ -20,40 +21,40 @@ namespace WireMock;
/// </summary>
public class RequestMessage : IRequestMessage
{
/// <inheritdoc cref="IRequestMessage.ClientIP" />
/// <inheritdoc />
public string ClientIP { get; }
/// <inheritdoc cref="IRequestMessage.Url" />
/// <inheritdoc />
public string Url { get; }
/// <inheritdoc cref="IRequestMessage.AbsoluteUrl" />
/// <inheritdoc />
public string AbsoluteUrl { get; }
/// <inheritdoc cref="IRequestMessage.ProxyUrl" />
/// <inheritdoc />
public string? ProxyUrl { get; set; }
/// <inheritdoc cref="IRequestMessage.DateTime" />
/// <inheritdoc />
public DateTime DateTime { get; set; }
/// <inheritdoc cref="IRequestMessage.Path" />
/// <inheritdoc />
public string Path { get; }
/// <inheritdoc cref="IRequestMessage.AbsolutePath" />
/// <inheritdoc />
public string AbsolutePath { get; }
/// <inheritdoc cref="IRequestMessage.PathSegments" />
/// <inheritdoc />
public string[] PathSegments { get; }
/// <inheritdoc cref="IRequestMessage.AbsolutePathSegments" />
/// <inheritdoc />
public string[] AbsolutePathSegments { get; }
/// <inheritdoc cref="IRequestMessage.Method" />
/// <inheritdoc />
public string Method { get; }
/// <inheritdoc cref="IRequestMessage.Headers" />
/// <inheritdoc />
public IDictionary<string, WireMockList<string>>? Headers { get; }
/// <inheritdoc cref="IRequestMessage.Cookies" />
/// <inheritdoc />
public IDictionary<string, string>? Cookies { get; }
/// <inheritdoc />
@@ -61,45 +62,50 @@ public class RequestMessage : IRequestMessage
/// <inheritdoc />
public IDictionary<string, WireMockList<string>>? QueryIgnoreCase { get; }
/// <inheritdoc cref="IRequestMessage.RawQuery" />
/// <inheritdoc />
public string RawQuery { get; }
/// <inheritdoc cref="IRequestMessage.BodyData" />
/// <inheritdoc />
public IBodyData? BodyData { get; }
/// <inheritdoc cref="IRequestMessage.Body" />
public string Body { get; }
/// <inheritdoc />
public string? Body { get; }
/// <inheritdoc cref="IRequestMessage.BodyAsJson" />
public object BodyAsJson { get; }
/// <inheritdoc />
public object? BodyAsJson { get; }
/// <inheritdoc cref="IRequestMessage.BodyAsBytes" />
public byte[] BodyAsBytes { get; }
/// <inheritdoc />
public byte[]? BodyAsBytes { get; }
/// <inheritdoc cref="IRequestMessage.DetectedBodyType" />
public string DetectedBodyType { get; }
#if MIMEKIT
/// <inheritdoc />
public object? BodyAsMimeMessage { get; }
#endif
/// <inheritdoc cref="IRequestMessage.DetectedBodyTypeFromContentType" />
public string DetectedBodyTypeFromContentType { get; }
/// <inheritdoc />
public string? DetectedBodyType { get; }
/// <inheritdoc cref="IRequestMessage.DetectedCompression" />
public string DetectedCompression { get; }
/// <inheritdoc />
public string? DetectedBodyTypeFromContentType { get; }
/// <inheritdoc cref="IRequestMessage.Host" />
/// <inheritdoc />
public string? DetectedCompression { get; }
/// <inheritdoc />
public string Host { get; }
/// <inheritdoc cref="IRequestMessage.Protocol" />
/// <inheritdoc />
public string Protocol { get; }
/// <inheritdoc cref="IRequestMessage.Port" />
/// <inheritdoc />
public int Port { get; }
/// <inheritdoc cref="IRequestMessage.Origin" />
/// <inheritdoc />
public string Origin { get; }
#if USE_ASPNETCORE
/// <inheritdoc cref="IRequestMessage.ClientCertificate" />
/// <inheritdoc />
public X509Certificate2? ClientCertificate { get; }
#endif
@@ -139,11 +145,11 @@ public class RequestMessage : IRequestMessage
#if USE_ASPNETCORE
, X509Certificate2? clientCertificate = null
#endif
)
)
{
Guard.NotNull(urlDetails, nameof(urlDetails));
Guard.NotNull(method, nameof(method));
Guard.NotNull(clientIP, nameof(clientIP));
Guard.NotNull(urlDetails);
Guard.NotNull(method);
Guard.NotNull(clientIP);
AbsoluteUrl = urlDetails.AbsoluteUrl.ToString();
Url = urlDetails.Url.ToString();
@@ -166,10 +172,22 @@ public class RequestMessage : IRequestMessage
Body = BodyData?.BodyAsString;
BodyAsJson = BodyData?.BodyAsJson;
BodyAsBytes = BodyData?.BodyAsBytes;
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
DetectedCompression = BodyData?.DetectedCompression;
#if MIMEKIT
try
{
BodyAsMimeMessage = MimeKitUtils.GetMimeMessage(BodyData, headers![HttpKnownHeaderNames.ContentType].First());
}
catch
{
// Ignore exception from MimeMessage.Load
}
#endif
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
Cookies = cookies;
RawQuery = urlDetails.Url.Query;

View File

@@ -19,6 +19,7 @@ using WireMock.Types;
using WireMock.Util;
using static WireMock.Util.CSharpFormatter;
namespace WireMock.Serialization;
internal class MappingConverter
@@ -46,7 +47,9 @@ internal class MappingConverter
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
var requestMessageBodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
var requestMessageGraphQLMatcher = request.GetRequestMessageMatcher<RequestMessageGraphQLMatcher>();
var requestMessageMultiPartMatcher = request.GetRequestMessageMatcher<RequestMessageMultiPartMatcher>();
var sb = new StringBuilder();
@@ -105,13 +108,33 @@ internal class MappingConverter
sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)");
}
if (bodyMatcher is { Matchers: { } })
#if GRAPHQL
if (requestMessageGraphQLMatcher is { Matchers: { } })
{
if (bodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
if (requestMessageGraphQLMatcher.Matchers.OfType<GraphQLMatcher>().FirstOrDefault() is { } graphQLMatcher && graphQLMatcher.GetPatterns().Any())
{
sb.AppendLine($" .WithGraphQLSchema({GetString(graphQLMatcher)})");
}
}
#endif
#if MIMEKIT
if (requestMessageMultiPartMatcher is { Matchers: { } })
{
if (requestMessageMultiPartMatcher.Matchers.OfType<MimePartMatcher>().Any())
{
sb.AppendLine(" // .WithMultiPart() is not yet supported");
}
}
#endif
if (requestMessageBodyMatcher is { Matchers: { } })
{
if (requestMessageBodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
{
sb.AppendLine($" .WithBody({GetString(wildcardMatcher)})");
}
else if (bodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
{
sb.AppendLine(@$" .WithBody(new JsonPartialMatcher(
value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())},
@@ -120,7 +143,7 @@ internal class MappingConverter
regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)}
))");
}
else if (bodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)
{
sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher(
value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())},
@@ -174,7 +197,7 @@ internal class MappingConverter
{
sb.AppendLine($" .WithBody({ToCSharpStringLiteral(bodyStringValue)})");
}
else if(bodyData.BodyAsJson is {} jsonBody)
else if (bodyData.BodyAsJson is { } jsonBody)
{
var anonymousObjectDefinition = ConvertToAnonymousObjectDefinition(jsonBody);
sb.AppendLine($" .WithBodyAsJson({anonymousObjectDefinition})");
@@ -216,6 +239,8 @@ internal class MappingConverter
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
var graphQLMatcher = request.GetRequestMessageMatcher<RequestMessageGraphQLMatcher>();
var multiPartMatcher = request.GetRequestMessageMatcher<RequestMessageMultiPartMatcher>();
var mappingModel = new MappingModel
{
@@ -301,7 +326,7 @@ internal class MappingConverter
mappingModel.Response.Delay = (int?)(response.Delay == Timeout.InfiniteTimeSpan ? TimeSpan.MaxValue.TotalMilliseconds : response.Delay?.TotalMilliseconds);
}
var nonNullableWebHooks = mapping.Webhooks?.Where(wh => wh != null).ToArray() ?? new IWebhook[0];
var nonNullableWebHooks = mapping.Webhooks?.Where(wh => wh != null).ToArray() ?? EmptyArray<IWebhook>.Value;
if (nonNullableWebHooks.Length == 1)
{
mappingModel.Webhook = WebhookMapper.Map(nonNullableWebHooks[0]);
@@ -311,18 +336,21 @@ internal class MappingConverter
mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
}
if (bodyMatcher?.Matchers != null)
var bodyMatchers = multiPartMatcher?.Matchers ?? graphQLMatcher?.Matchers ?? bodyMatcher?.Matchers;
var matchOperator = multiPartMatcher?.MatchOperator ?? graphQLMatcher?.MatchOperator ?? bodyMatcher?.MatchOperator;
if (bodyMatchers != null && matchOperator != null)
{
mappingModel.Request.Body = new BodyModel();
if (bodyMatcher.Matchers.Length == 1)
if (bodyMatchers.Length == 1)
{
mappingModel.Request.Body.Matcher = _mapper.Map(bodyMatcher.Matchers[0]);
mappingModel.Request.Body.Matcher = _mapper.Map(bodyMatchers[0]);
}
else if (bodyMatcher.Matchers.Length > 1)
else if (bodyMatchers.Length > 1)
{
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatcher.Matchers);
mappingModel.Request.Body.MatchOperator = bodyMatcher.MatchOperator.ToString();
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatchers);
mappingModel.Request.Body.MatchOperator = matchOperator.ToString();
}
}
@@ -506,6 +534,4 @@ internal class MappingConverter
return newDictionary;
}
}

View File

@@ -71,7 +71,15 @@ internal class MatcherMapper
case nameof(ExactObjectMatcher):
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
#if GRAPHQL
case nameof(GraphQLMatcher):
return new GraphQLMatcher(stringPatterns[0].GetPattern(), matchBehaviour, throwExceptionWhenMatcherFails, matchOperator);
#endif
#if MIMEKIT
case nameof(MimePartMatcher):
return CreateMimePartMatcher(matchBehaviour, matcher, throwExceptionWhenMatcherFails);
#endif
case nameof(RegexMatcher):
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended, matchOperator);
@@ -123,12 +131,7 @@ internal class MatcherMapper
public MatcherModel[]? Map(IEnumerable<IMatcher>? matchers)
{
if (matchers == null)
{
return null;
}
return matchers.Where(m => m != null).Select(Map).ToArray()!;
return matchers?.Where(m => m != null).Select(Map).ToArray();
}
public MatcherModel? Map(IMatcher? matcher)
@@ -192,6 +195,15 @@ internal class MatcherMapper
case ExactObjectMatcher exactObjectMatcher:
model.Pattern = exactObjectMatcher.ValueAsObject ?? exactObjectMatcher.ValueAsBytes;
break;
#if MIMEKIT
case MimePartMatcher mimePartMatcher:
model.ContentDispositionMatcher = Map(mimePartMatcher.ContentDispositionMatcher);
model.ContentMatcher = Map(mimePartMatcher.ContentMatcher);
model.ContentTransferEncodingMatcher = Map(mimePartMatcher.ContentTransferEncodingMatcher);
model.ContentTypeMatcher = Map(mimePartMatcher.ContentTypeMatcher);
break;
#endif
}
return model;
@@ -221,7 +233,7 @@ internal class MatcherMapper
return new[] { new AnyOf<string, StringPattern>(new StringPattern { Pattern = pattern, PatternAsFile = patternAsFile }) };
}
return new AnyOf<string, StringPattern>[0];
return EmptyArray<AnyOf<string, StringPattern>>.Value;
}
private static ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> stringPattern, bool throwException)
@@ -238,4 +250,16 @@ internal class MatcherMapper
return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException);
}
#if MIMEKIT
private MimePartMatcher CreateMimePartMatcher(MatchBehaviour matchBehaviour, MatcherModel? matcher, bool throwExceptionWhenMatcherFails)
{
var contentTypeMatcher = Map(matcher?.ContentTypeMatcher) as IStringMatcher;
var contentDispositionMatcher = Map(matcher?.ContentDispositionMatcher) as IStringMatcher;
var contentTransferEncodingMatcher = Map(matcher?.ContentTransferEncodingMatcher) as IStringMatcher;
var contentMatcher = Map(matcher?.ContentMatcher);
return new MimePartMatcher(matchBehaviour, contentTypeMatcher, contentDispositionMatcher, contentTransferEncodingMatcher, contentMatcher, throwExceptionWhenMatcherFails);
}
#endif
}

View File

@@ -0,0 +1,42 @@
#if MIMEKIT
using System;
using System.IO;
using System.Text;
using MimeKit;
using WireMock.Http;
using WireMock.Types;
namespace WireMock.Util;
internal static class MimeKitUtils
{
public static MimeMessage GetMimeMessage(IBodyData? bodyData, string contentTypeHeaderValue)
{
var bytes = bodyData?.DetectedBodyType switch
{
// If the body is bytes, use the BodyAsBytes to match on.
BodyType.Bytes => bodyData.BodyAsBytes!,
// If the body is a String or MultiPart, use the BodyAsString to match on.
BodyType.String or BodyType.MultiPart => Encoding.UTF8.GetBytes(bodyData.BodyAsString!),
_ => throw new NotSupportedException()
};
var fixedBytes = FixBytes(bytes, contentTypeHeaderValue);
return MimeMessage.Load(new MemoryStream(fixedBytes));
}
private static byte[] FixBytes(byte[] bytes, WireMockList<string> contentType)
{
var contentTypeBytes = Encoding.UTF8.GetBytes($"{HttpKnownHeaderNames.ContentType}: {contentType}\r\n\r\n");
var result = new byte[contentTypeBytes.Length + bytes.Length];
Buffer.BlockCopy(contentTypeBytes, 0, result, 0, contentTypeBytes.Length);
Buffer.BlockCopy(bytes, 0, result, contentTypeBytes.Length, bytes.Length);
return result;
}
}
#endif

View File

@@ -0,0 +1,12 @@
using System.IO;
using System.Text;
namespace WireMock.Util;
internal static class StreamUtils
{
public static Stream CreateStream(string s)
{
return new MemoryStream(Encoding.UTF8.GetBytes(s));
}
}

View File

@@ -50,16 +50,20 @@
<DefineConstants>$(DefineConstants);OPENAPIPARSER</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Matchers\MultiPartMatcher.cs" />
<Compile Remove="Util\FileSystemWatcherExtensions.cs" />
<Compile Remove="Matchers\Request\IRequestMatcher.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" />
<PackageReference Include="JsonConverter.Abstractions" Version="0.4.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
<PackageReference Include="NSwag.Core" Version="13.16.1" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
@@ -154,6 +158,12 @@
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
</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" />
<PackageReference Include="MimeKitLite" Version="4.1.0.1" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
@@ -180,13 +190,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Handlebars.Net.Helpers" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.3.15" />
<PackageReference Include="Handlebars.Net.Helpers" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.4.0" />
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.4.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -210,6 +210,36 @@ public class WireMockAssertionsTests : IDisposable
.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]
public async Task HaveReceivedACall_AtUrl_WhenACallWasMadeToUrl_Should_BeOK()
{

View File

@@ -14,6 +14,17 @@
},
Methods: [
GET
],
Params: [
{
Name: test,
Matchers: [
{
Name: LinqMatcher,
Pattern: it.Length < 10
}
]
}
]
},
Response: {

View File

@@ -14,6 +14,17 @@
},
Methods: [
GET
],
Params: [
{
Name: test,
Matchers: [
{
Name: LinqMatcher,
Pattern: it.Length < 10
}
]
}
]
},
Response: {

View File

@@ -6,6 +6,7 @@ using VerifyTests;
using VerifyXunit;
using WireMock.Handlers;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Net.Tests.VerifyExtensions;
using WireMock.Owin;
using WireMock.RequestBuilders;
@@ -65,6 +66,7 @@ public class MappingBuilderTests
_sut.Given(Request.Create()
.WithPath("/foo")
.WithParam("test", new LinqMatcher("it.Length < 10"))
.UsingGet()
)
.WithGuid(MappingGuid)

View File

@@ -0,0 +1,142 @@
#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

View File

@@ -199,6 +199,27 @@ public class JsonPartialMatcherTests
Assert.Equal(0.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_GuidAsString_UsingRegex()
{
var guid = new Guid("1111238e-b775-44a9-a263-95e570135c94");
var matcher = new JsonPartialMatcher(new {
Id = 1,
Name = "^1111[a-fA-F0-9]{4}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"
}, false, false, true);
// Act
var jObject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue(guid) }
};
double match = matcher.IsMatch(jObject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithIgnoreCaseTrue_JObject()
{
@@ -281,6 +302,25 @@ public class JsonPartialMatcherTests
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_GuidAsString()
{
// Assign
var guid = Guid.NewGuid();
var matcher = new JsonPartialMatcher(new { Id = 1, Name = guid });
// Act
var jObject = new JObject
{
{ "Id", new JValue(1) },
{ "Name", new JValue(guid.ToString()) }
};
double match = matcher.IsMatch(jObject);
// Assert
Assert.Equal(1.0, match);
}
[Fact]
public void JsonPartialMatcher_IsMatch_WithIgnoreCaseTrue_JObjectAsString()
{

View File

@@ -11,7 +11,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_GetName()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher("X");
// Act
@@ -24,7 +24,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_GetPatterns()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher("X");
// Act
@@ -37,7 +37,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_ByteArray()
{
// Assign
// Arrange
var bytes = EmptyArray<byte>.Value;
var matcher = new JsonPathMatcher("");
@@ -51,7 +51,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_NullString()
{
// Assign
// Arrange
string? s = null;
var matcher = new JsonPathMatcher("");
@@ -65,7 +65,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_NullObject()
{
// Assign
// Arrange
object? o = null;
var matcher = new JsonPathMatcher("");
@@ -79,7 +79,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_String_Exception_Mismatch()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher("xxx");
// Act
@@ -92,7 +92,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher("");
// Act
@@ -105,7 +105,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_AnonymousObject()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
// Act
@@ -115,10 +115,51 @@ public class JsonPathMatcherTests
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]
public void JsonPathMatcher_IsMatch_JObject()
{
// Assign
// Arrange
string[] patterns = { "$..[?(@.Id == 1)]" };
var matcher = new JsonPathMatcher(patterns);
@@ -137,7 +178,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_JObject_Parsed()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
// Act
@@ -150,7 +191,7 @@ public class JsonPathMatcherTests
[Fact]
public void JsonPathMatcher_IsMatch_RejectOnMatch()
{
// Assign
// Arrange
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "$..[?(@.Id == 1)]");
// Act
@@ -159,4 +200,128 @@ public class JsonPathMatcherTests
// Assert
Check.That(match).IsEqualTo(0.0);
}
}
[Fact]
public void JsonPathMatcher_IsMatch_ArrayOneLevel()
{
// Arrange
var matcher = new JsonPathMatcher("$.arr[0].line1");
// Act
double match = matcher.IsMatch(JObject.Parse(@"{
""name"": ""PathSelectorTest"",
""test"": ""test"",
""test2"": ""test2"",
""arr"": [{
""line1"": ""line1"",
}]
}"));
// Assert
Check.That(match).IsEqualTo(1.0);
}
[Fact]
public void JsonPathMatcher_IsMatch_ObjectMatch()
{
// Arrange
var matcher = new JsonPathMatcher("$.test");
// Act
double match = matcher.IsMatch(JObject.Parse(@"{
""name"": ""PathSelectorTest"",
""test"": ""test"",
""test2"": ""test2"",
""arr"": [
{
""line1"": ""line1"",
}
]
}"));
// Assert
Check.That(match).IsEqualTo(1.0);
}
[Fact]
public void JsonPathMatcher_IsMatch_DoesntMatch()
{
// Arrange
var matcher = new JsonPathMatcher("$.test3");
// Act
double match = matcher.IsMatch(JObject.Parse(@"{
""name"": ""PathSelectorTest"",
""test"": ""test"",
""test2"": ""test2"",
""arr"": [
{
""line1"": ""line1"",
}
]
}"));
// Assert
Check.That(match).IsEqualTo(0.0);
}
[Fact]
public void JsonPathMatcher_IsMatch_DoesntMatchInArray()
{
// Arrange
var matcher = new JsonPathMatcher("$arr[0].line1");
// Act
double match = matcher.IsMatch(JObject.Parse(@"{
""name"": ""PathSelectorTest"",
""test"": ""test"",
""test2"": ""test2"",
""arr"": []
}"));
// Assert
Check.That(match).IsEqualTo(0.0);
}
[Fact]
public void JsonPathMatcher_IsMatch_DoesntMatchNoObjectsInArray()
{
// Arrange
var matcher = new JsonPathMatcher("$arr[2].line1");
// Act
double match = matcher.IsMatch(JObject.Parse(@"{
""name"": ""PathSelectorTest"",
""test"": ""test"",
""test2"": ""test2"",
""arr"": []
}"));
// Assert
Check.That(match).IsEqualTo(0.0);
}
[Fact]
public void JsonPathMatcher_IsMatch_NestedArrays()
{
// Arrange
var matcher = new JsonPathMatcher("$.arr[0].sub[0].subline1");
// Act
double match = matcher.IsMatch(JObject.Parse(@"{
""name"": ""PathSelectorTest"",
""test"": ""test"",
""test2"": ""test2"",
""arr"": [{
""line1"": ""line1"",
""sub"":[
{
""subline1"":""subline1""
}]
}]
}"));
// Assert
Check.That(match).IsEqualTo(1.0);
}
}

View File

@@ -0,0 +1,99 @@
#if MIMEKIT
using System;
using System.Linq;
using FluentAssertions;
using MimeKit;
using WireMock.Matchers;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.Matchers;
public class MimePartMatcherTests
{
private const string TestMultiPart = @"From:
Date: Sun, 23 Jul 2023 16:13:13 +0200
Subject:
Message-Id: <HZ3K1HEAJKU4.IO57XCVO4BWV@desktop-6dd5qi2>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=""=-5XgmpXt0XOfzdtcgNJc2ZQ==""
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/plain; charset=utf-8
This is some plain text
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/json; charset=utf-8
{
""Key"": ""Value""
}
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: image/png; name=image.png
Content-Disposition: attachment; filename=image.png
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjl
AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
--=-5XgmpXt0XOfzdtcgNJc2ZQ==--
";
[Fact]
public void MimePartMatcher_IsMatch_Part_TextPlain()
{
// Arrange
var message = MimeMessage.Load(StreamUtils.CreateStream(TestMultiPart));
var part = (MimePart)message.BodyParts.ToArray()[0];
// Act
var contentTypeMatcher = new ContentTypeMatcher("text/plain");
var contentMatcher = new ExactMatcher("This is some plain text");
var matcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, contentTypeMatcher, null, null, contentMatcher);
var result = matcher.IsMatch(part);
// Assert
matcher.Name.Should().Be("MimePartMatcher");
result.Should().Be(MatchScores.Perfect);
}
[Fact]
public void MimePartMatcher_IsMatch_Part_TextJson()
{
// Arrange
var message = MimeMessage.Load(StreamUtils.CreateStream(TestMultiPart));
var part = (MimePart)message.BodyParts.ToArray()[1];
// Act
var contentTypeMatcher = new ContentTypeMatcher("text/json");
var contentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var matcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, contentTypeMatcher, null, null, contentMatcher);
var result = matcher.IsMatch(part);
// Assert
result.Should().Be(MatchScores.Perfect);
}
[Fact]
public void MimePartMatcher_IsMatch_Part_ImagePng()
{
// Arrange
var message = MimeMessage.Load(StreamUtils.CreateStream(TestMultiPart));
var part = (MimePart)message.BodyParts.ToArray()[2];
// Act
var contentTypeMatcher = new ContentTypeMatcher("image/png");
var contentDispositionMatcher = new ExactMatcher("attachment; filename=\"image.png\"");
var contentTransferEncodingMatcher = new ExactMatcher("base64");
var contentMatcher = new ExactObjectMatcher(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"));
var matcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, contentTypeMatcher, contentDispositionMatcher, contentTransferEncodingMatcher, contentMatcher);
var result = matcher.IsMatch(part);
// Assert
result.Should().Be(MatchScores.Perfect);
}
}
#endif

View File

@@ -8,9 +8,9 @@ using WireMock.Types;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests;
namespace WireMock.Net.Tests.RequestBuilders;
public class RequestTests
public class RequestBuilderTests
{
private const string ClientIp = "::1";

View File

@@ -1,17 +1,28 @@
using System;
using FluentAssertions;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JsonConverter.Abstractions;
using Moq;
using Newtonsoft.Json;
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.RequestBuilders;
using WireMock.Types;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests.RequestBuilders;
public class RequestBuilderWithBodyTests
{
private const string ClientIp = "::1";
[Fact]
public void RequestBuilder_WithBody_IMatcher()
public void Request_WithBody_IMatcher()
{
// Assign
var matcher = new WildcardMatcher("x");
@@ -26,7 +37,7 @@ public class RequestBuilderWithBodyTests
}
[Fact]
public void RequestBuilder_WithBody_IMatchers()
public void Request_WithBody_IMatchers()
{
// Assign
var matcher1 = new WildcardMatcher("x");
@@ -40,4 +51,409 @@ public class RequestBuilderWithBodyTests
matchers.Should().HaveCount(1);
((RequestMessageBodyMatcher)matchers[0]).Matchers.Should().Contain(new[] { matcher1, matcher2 });
}
[Fact]
public void Request_WithBody_FuncString()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b != null && b.Contains("b"));
// Act
var body = new BodyData
{
BodyAsString = "b",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncJson()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b != null);
// Act
var body = new BodyData
{
BodyAsJson = 123,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncFormUrlEncoded()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IDictionary<string, string>? values) => values != null);
// Act
var body = new BodyData
{
BodyAsFormUrlEncoded = new Dictionary<string, string>(),
DetectedBodyTypeFromContentType = BodyType.FormUrlEncoded,
DetectedBodyType = BodyType.FormUrlEncoded
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncBodyData()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IBodyData? b) => b != null);
// Act
var body = new BodyData
{
BodyAsJson = 123,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncByteArray()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((byte[]? b) => b != null);
// Act
var body = new BodyData
{
BodyAsBytes = new byte[0],
DetectedBodyType = BodyType.Bytes
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyExactMatcher()
{
// Arrange
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(new ExactMatcher("cat"));
// Act
var body = new BodyData
{
BodyAsString = "cat",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_BodyDataAsString_Using_WildcardMatcher()
{
// Arrange
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithBody(new WildcardMatcher("H*o*"));
// Act
var body = new BodyData
{
BodyAsString = "Hello world!",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
spec.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
[Fact]
public void Request_WithBody_BodyDataAsJson_Using_WildcardMatcher()
{
// Arrange
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithBody(new WildcardMatcher("*Hello*"));
// Act
var body = new BodyData
{
BodyAsJson = new { Hi = "Hello world!" },
BodyAsString = "{ Hi = \"Hello world!\" }",
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
spec.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
[Fact]
public void Request_WithBody_XPathMatcher_true()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 3]"));
// Act
var body = new BodyData
{
BodyAsString = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
<todo-item id='a2'>def</todo-item>
<todo-item id='a3'>xyz</todo-item>
</todo-list>",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_XPathMatcher_false()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 99]"));
// Act
var body = new BodyData
{
BodyAsString = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
<todo-item id='a2'>def</todo-item>
<todo-item id='a3'>xyz</todo-item>
</todo-list>",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithBody_JsonPathMatcher_true()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
// Act
var body = new BodyData
{
BodyAsString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyJson_PathMatcher_false()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"));
// Act
var body = new BodyData
{
BodyAsString = "{ \"things\": { \"name\": \"Wiremock\" } }",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Object_JsonPathMatcher_true()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
// Act
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Array_JsonPathMatcher_1()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..books[?(@.price < 10)]"));
// Act
string jsonString = "{ \"books\": [ { \"category\": \"test1\", \"price\": 8.95 }, { \"category\": \"test2\", \"price\": 20 } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Array_JsonPathMatcher_2()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..[?(@.Id == 1)]"));
// Act
string jsonString = "{ \"Id\": 1, \"Name\": \"Test\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
double result = spec.GetMatchingScore(request, requestMatchResult);
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsObject_ExactObjectMatcher_true()
{
// Assign
object body = DateTime.MinValue;
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
var bodyData = new BodyData
{
BodyAsJson = DateTime.MinValue,
DetectedBodyType = BodyType.Json
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_UsingObject()
{
// Assign
object body = new
{
Test = "abc"
};
var requestBuilder = Request.Create().UsingAnyMethod().WithBodyAsJson(body);
var bodyData = new BodyData
{
BodyAsString = JsonConvert.SerializeObject(body),
DetectedBodyType = BodyType.String
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_WithIJsonConverter_UsingObject()
{
// Assign
var jsonConverterMock = new Mock<IJsonConverter>();
jsonConverterMock.Setup(j => j.Serialize(It.IsAny<object>(), It.IsAny<JsonConverterOptions>())).Returns("test");
object body = new
{
Any = "key"
};
var requestBuilder = Request.Create().UsingAnyMethod().WithBodyAsJson(body, jsonConverterMock.Object);
var bodyData = new BodyData
{
BodyAsString = "test",
DetectedBodyType = BodyType.String
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Theory]
[InlineData(new byte[] { 1 }, BodyType.Bytes)]
[InlineData(new byte[] { 48, 49, 50 }, BodyType.Bytes)]
[InlineData(new byte[] { 48, 49, 50 }, BodyType.String)]
public void Request_WithBodyAsBytes_ExactObjectMatcher_true(byte[] bytes, BodyType detectedBodyType)
{
// Assign
byte[] body = bytes;
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
var bodyData = new BodyData
{
BodyAsBytes = bytes,
DetectedBodyType = detectedBodyType
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
requestBuilder.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
}

View File

@@ -0,0 +1,67 @@
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.RequestBuilders;
using Xunit;
namespace WireMock.Net.Tests.RequestBuilders;
public class RequestBuilderWithClientIPTests
{
[Fact]
public void Request_WithClientIP_Match_Ok()
{
// given
var spec = Request.Create().WithClientIP("127.0.0.2", "1.1.1.1");
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithClientIP_Match_Fail()
{
// given
var spec = Request.Create().WithClientIP("127.0.0.2");
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "192.1.1.1");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(0.0);
}
[Fact]
public void Request_WithClientIP_WildcardMatcher()
{
// given
var spec = Request.Create().WithClientIP(new WildcardMatcher("127.0.0.2"));
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithClientIP_Func()
{
// given
var spec = Request.Create().WithClientIP(c => c.Contains("."));
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
}

View File

@@ -0,0 +1,71 @@
#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

View File

@@ -0,0 +1,47 @@
#if MIMEKIT
using System.Collections.Generic;
using FluentAssertions;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using Xunit;
namespace WireMock.Net.Tests.RequestBuilders;
public class RequestBuilderWithMultiPartTests
{
[Fact]
public void RequestBuilder_WithMultiPart_MimePartMatcher()
{
// Arrange
var matcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, null, null, null, null);
// Act
var requestBuilder = (Request)Request.Create().WithMultiPart(matcher);
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
matchers.Should().HaveCount(1);
((RequestMessageMultiPartMatcher)matchers[0]).Matchers.Should().HaveCount(1).And.ContainItemsAssignableTo<MimePartMatcher>();
}
[Fact]
public void RequestBuilder_WithMultiPart_MimePartMatchers()
{
// Arrange
var matcher1 = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, null, null, null, null);
var matcher2 = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, null, null, null, null);
// Act
var requestBuilder = (Request)Request.Create().WithMultiPart(MatchBehaviour.RejectOnMatch, matcher1, matcher2);
// Assert
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
matchers.Should().HaveCount(1);
var x = ((RequestMessageMultiPartMatcher)matchers[0]);
x.MatchBehaviour.Should().Be(MatchBehaviour.RejectOnMatch);
x.Matchers.Should().HaveCount(2).And.ContainItemsAssignableTo<MimePartMatcher>();
}
}
#endif

View File

@@ -0,0 +1,238 @@
using System.Collections.Generic;
using NFluent;
using WireMock.Matchers;
using Xunit;
using WireMock.RequestBuilders;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Net.Tests.RequestBuilders;
public class RequestBuilderWithPathTests
{
private const string ClientIp = "::1";
[Fact]
public void Request_WithPath_Spaces()
{
// Assign
var spec = Request.Create().WithPath("/path/a b").UsingAnyMethod();
// when
var body = new BodyData();
var request = new RequestMessage(new UrlDetails("http://localhost/path/a b"), "GET", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_WithHeader_Match()
{
// given
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithHeader("X-toto", "tata");
// when
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath()
{
// given
var spec = Request.Create().WithPath("/foo");
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPaths()
{
var requestBuilder = Request.Create().WithPath("/x1", "/x2");
var request1 = new RequestMessage(new UrlDetails("http://localhost/x1"), "blabla", ClientIp);
var request2 = new RequestMessage(new UrlDetails("http://localhost/x2"), "blabla", ClientIp);
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request1, requestMatchResult)).IsEqualTo(1.0);
Check.That(requestBuilder.GetMatchingScore(request2, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPathFunc()
{
// given
var spec = Request.Create().WithPath(url => url.EndsWith("/foo"));
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_RegexMatcher_HasMatch()
{
// given
var spec = Request.Create().WithPath(new RegexMatcher("^/foo"));
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo/bar"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPathRegexMatcher_HasNoMatch()
{
// given
var spec = Request.Create().WithPath("/foo");
// when
var request = new RequestMessage(new UrlDetails("http://localhost/bar"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithPath_RegexMatcher_WithPatternAsFile_HasMatch()
{
// Arrange
var pattern = new StringPattern
{
Pattern = "^/foo",
PatternAsFile = "c:\\x.txt"
};
var spec = Request.Create().WithPath(new RegexMatcher(pattern));
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo/bar"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_specify_requests_matching_given_path_and_method_delete()
{
// given
var spec = Request.Create().WithPath("/foo").UsingDelete();
// when
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "Delete", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_specify_requests_matching_given_path_and_method_get()
{
// given
var spec = Request.Create().WithPath("/foo").UsingGet();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_specify_requests_matching_given_path_and_method_head()
{
// given
var spec = Request.Create().WithPath("/foo").UsingHead();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_specify_requests_matching_given_path_and_method_post()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPost();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_specify_requests_matching_given_path_and_method_put()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_specify_requests_matching_given_path_and_method_patch()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPatch();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PATCH", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_Should_exclude_requests_matching_given_path_but_not_http_method()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
}

View File

@@ -0,0 +1,194 @@
#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

View File

@@ -0,0 +1,84 @@
#if MIMEKIT
using System;
using System.Collections.Generic;
using FluentAssertions;
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 RequestMessageMultiPartMatcherTests
{
private const string TestMultiPart = @"--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/plain; charset=utf-8
This is some plain text
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/json; charset=utf-8
{
""Key"": ""Value""
}
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: image/png; name=image.png
Content-Disposition: attachment; filename=image.png
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjl
AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
--=-5XgmpXt0XOfzdtcgNJc2ZQ==--
";
[Fact]
public void RequestMessageBodyMatcher_GetMatchingScore_BodyAsMultiPart()
{
// Assign
var body = new BodyData
{
BodyAsString = TestMultiPart,
DetectedBodyType = BodyType.MultiPart
};
var textPlainContentTypeMatcher = new ContentTypeMatcher("text/plain");
var textPlainContentMatcher = new ExactMatcher("This is some plain text");
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
var partTextJsonContentTypeMatcher = new ContentTypeMatcher("text/json");
var partTextJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var partTextMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, partTextJsonContentTypeMatcher, null, null, partTextJsonContentMatcher);
var imagePngContentTypeMatcher = new ContentTypeMatcher("image/png");
var imagePngContentDispositionMatcher = new ExactMatcher("attachment; filename=\"image.png\"");
var imagePngContentTransferEncodingMatcher = new ExactMatcher("base64");
var imagePngContentMatcher = new ExactObjectMatcher(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC"));
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, imagePngContentTypeMatcher, imagePngContentDispositionMatcher, imagePngContentTransferEncodingMatcher, imagePngContentMatcher);
var matchers = new IMatcher[]
{
textPlainMatcher,
partTextMatcher,
imagePngMatcher
};
var headers = new Dictionary<string, string[]>
{
{ "Content-Type", new[] { @"multipart/mixed; boundary=""=-5XgmpXt0XOfzdtcgNJc2ZQ==""" } }
};
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body, headers);
var matcher = new RequestMessageMultiPartMatcher(matchers);
// Act
var result = new RequestMatchResult();
var score = matcher.GetMatchingScore(requestMessage, result);
// Assert
score.Should().Be(MatchScores.Perfect);
}
}
#endif

View File

@@ -1,428 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using FluentAssertions;
using JsonConverter.Abstractions;
using Moq;
using Newtonsoft.Json;
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.RequestBuilders;
using WireMock.Types;
using WireMock.Util;
using Xunit;
namespace WireMock.Net.Tests
{
public class RequestWithBodyTests
{
private const string ClientIp = "::1";
[Fact]
public void Request_WithBody_FuncString()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b.Contains("b"));
// Act
var body = new BodyData
{
BodyAsString = "b",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncJson()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(b => b != null);
// Act
var body = new BodyData
{
BodyAsJson = 123,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncFormUrlEncoded()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IDictionary<string, string>? values) => values != null);
// Act
var body = new BodyData
{
BodyAsFormUrlEncoded = new Dictionary<string, string>(),
DetectedBodyTypeFromContentType = BodyType.FormUrlEncoded,
DetectedBodyType = BodyType.FormUrlEncoded
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncBodyData()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IBodyData? b) => b != null);
// Act
var body = new BodyData
{
BodyAsJson = 123,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_FuncByteArray()
{
// Assign
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((byte[]? b) => b != null);
// Act
var body = new BodyData
{
BodyAsBytes = new byte[0],
DetectedBodyType = BodyType.Bytes
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyExactMatcher()
{
// Arrange
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(new ExactMatcher("cat"));
// Act
var body = new BodyData
{
BodyAsString = "cat",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBody_BodyDataAsString_Using_WildcardMatcher()
{
// Arrange
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithBody(new WildcardMatcher("H*o*"));
// Act
var body = new BodyData
{
BodyAsString = "Hello world!",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
spec.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
[Fact]
public void Request_WithBody_BodyDataAsJson_Using_WildcardMatcher()
{
// Arrange
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithBody(new WildcardMatcher("*Hello*"));
// Act
var body = new BodyData
{
BodyAsJson = new { Hi = "Hello world!" },
BodyAsString = "{ Hi = \"Hello world!\" }",
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
spec.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
[Fact]
public void Request_WithBodyXPathMatcher_true()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 3]"));
// Act
var body = new BodyData
{
BodyAsString = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
<todo-item id='a2'>def</todo-item>
<todo-item id='a3'>xyz</todo-item>
</todo-list>",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyXPathMatcher_false()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new XPathMatcher("/todo-list[count(todo-item) = 99]"));
// Act
var body = new BodyData
{
BodyAsString = @"
<todo-list>
<todo-item id='a1'>abc</todo-item>
<todo-item id='a2'>def</todo-item>
<todo-item id='a3'>xyz</todo-item>
</todo-list>",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithBodyJsonPathMatcher_true()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
// Act
var body = new BodyData
{
BodyAsString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyJsonPathMatcher_false()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$.things[?(@.name == 'RequiredThing')]"));
// Act
var body = new BodyData
{
BodyAsString = "{ \"things\": { \"name\": \"Wiremock\" } }",
DetectedBodyType = BodyType.String
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Object_JsonPathMatcher_true()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..things[?(@.name == 'RequiredThing')]"));
// Act
string jsonString = "{ \"things\": [ { \"name\": \"RequiredThing\" }, { \"name\": \"Wiremock\" } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Array_JsonPathMatcher_1()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..books[?(@.price < 10)]"));
// Act
string jsonString = "{ \"books\": [ { \"category\": \"test1\", \"price\": 8.95 }, { \"category\": \"test2\", \"price\": 20 } ] }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_Array_JsonPathMatcher_2()
{
// Arrange
var spec = Request.Create().UsingAnyMethod().WithBody(new JsonPathMatcher("$..[?(@.Id == 1)]"));
// Act
string jsonString = "{ \"Id\": 1, \"Name\": \"Test\" }";
var bodyData = new BodyData
{
BodyAsJson = JsonConvert.DeserializeObject(jsonString),
BodyAsString = jsonString,
Encoding = Encoding.UTF8,
DetectedBodyType = BodyType.Json
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
double result = spec.GetMatchingScore(request, requestMatchResult);
Check.That(result).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsObject_ExactObjectMatcher_true()
{
// Assign
object body = DateTime.MinValue;
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
var bodyData = new BodyData
{
BodyAsJson = DateTime.MinValue,
DetectedBodyType = BodyType.Json
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_UsingObject()
{
// Assign
object body = new
{
Test = "abc"
};
var requestBuilder = Request.Create().UsingAnyMethod().WithBodyAsJson(body);
var bodyData = new BodyData
{
BodyAsString = JsonConvert.SerializeObject(body),
DetectedBodyType = BodyType.String
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithBodyAsJson_WithIJsonConverter_UsingObject()
{
// Assign
var jsonConverterMock = new Mock<IJsonConverter>();
jsonConverterMock.Setup(j => j.Serialize(It.IsAny<object>(), It.IsAny<JsonConverterOptions>())).Returns("test");
object body = new
{
Any = "key"
};
var requestBuilder = Request.Create().UsingAnyMethod().WithBodyAsJson(body, jsonConverterMock.Object);
var bodyData = new BodyData
{
BodyAsString = "test",
DetectedBodyType = BodyType.String
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Theory]
[InlineData(new byte[] { 1 }, BodyType.Bytes)]
[InlineData(new byte[] { 48, 49, 50 }, BodyType.Bytes)]
[InlineData(new byte[] { 48, 49, 50 }, BodyType.String)]
public void Request_WithBodyAsBytes_ExactObjectMatcher_true(byte[] bytes, BodyType detectedBodyType)
{
// Assign
byte[] body = bytes;
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
var bodyData = new BodyData
{
BodyAsBytes = bytes,
DetectedBodyType = detectedBodyType
};
// Act
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, bodyData);
// Assert
var requestMatchResult = new RequestMatchResult();
requestBuilder.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
}
}
}

View File

@@ -1,68 +0,0 @@
using NFluent;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.RequestBuilders;
using Xunit;
namespace WireMock.Net.Tests
{
public class RequestWithClientIPTests
{
[Fact]
public void Request_WithClientIP_Match_Ok()
{
// given
var spec = Request.Create().WithClientIP("127.0.0.2", "1.1.1.1");
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithClientIP_Match_Fail()
{
// given
var spec = Request.Create().WithClientIP("127.0.0.2");
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "192.1.1.1");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(0.0);
}
[Fact]
public void Request_WithClientIP_WildcardMatcher()
{
// given
var spec = Request.Create().WithClientIP(new WildcardMatcher("127.0.0.2"));
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithClientIP_Func()
{
// given
var spec = Request.Create().WithClientIP(c => c.Contains("."));
// when
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.2");
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
}
}

View File

@@ -1,239 +0,0 @@
using System.Collections.Generic;
using NFluent;
using WireMock.Matchers;
using Xunit;
using WireMock.RequestBuilders;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.Util;
namespace WireMock.Net.Tests
{
public class RequestWithPathTests
{
private const string ClientIp = "::1";
[Fact]
public void Request_WithPath_Spaces()
{
// Assign
var spec = Request.Create().WithPath("/path/a b").UsingAnyMethod();
// when
var body = new BodyData();
var request = new RequestMessage(new UrlDetails("http://localhost/path/a b"), "GET", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath_WithHeader_Match()
{
// given
var spec = Request.Create().WithPath("/foo").UsingAnyMethod().WithHeader("X-toto", "tata");
// when
var body = new BodyData
{
BodyAsString = "abc"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp, body, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPath()
{
// given
var spec = Request.Create().WithPath("/foo");
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPaths()
{
var requestBuilder = Request.Create().WithPath("/x1", "/x2");
var request1 = new RequestMessage(new UrlDetails("http://localhost/x1"), "blabla", ClientIp);
var request2 = new RequestMessage(new UrlDetails("http://localhost/x2"), "blabla", ClientIp);
var requestMatchResult = new RequestMatchResult();
Check.That(requestBuilder.GetMatchingScore(request1, requestMatchResult)).IsEqualTo(1.0);
Check.That(requestBuilder.GetMatchingScore(request2, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPathFunc()
{
// given
var spec = Request.Create().WithPath(url => url.EndsWith("/foo"));
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPathRegexMatcher_HasMatch()
{
// given
var spec = Request.Create().WithPath(new RegexMatcher("^/foo"));
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo/bar"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Request_WithPathRegexMatcher_HasNoMatch()
{
// given
var spec = Request.Create().WithPath("/foo");
// when
var request = new RequestMessage(new UrlDetails("http://localhost/bar"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Request_WithPathRegexMatcher_WithPatternAsFile_HasMatch()
{
// Arrange
var pattern = new StringPattern
{
Pattern = "^/foo",
PatternAsFile = "c:\\x.txt"
};
var spec = Request.Create().WithPath(new RegexMatcher(pattern));
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo/bar"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_delete()
{
// given
var spec = Request.Create().WithPath("/foo").UsingDelete();
// when
var body = new BodyData
{
BodyAsString = "whatever"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "Delete", ClientIp, body);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_get()
{
// given
var spec = Request.Create().WithPath("/foo").UsingGet();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_head()
{
// given
var spec = Request.Create().WithPath("/foo").UsingHead();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_post()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPost();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_put()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PUT", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_patch()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPatch();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "PATCH", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_exclude_requests_matching_given_path_but_not_http_method()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
}
}

View File

@@ -34,7 +34,7 @@ public class ResponseWithHandlebarsXPathTests
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_XPath_SelectSingleNode_Request_BodyAsString()
public async Task Response_ProvideResponse_Handlebars_XPath_SelectNode_Request_BodyAsString()
{
// Assign
var body = new BodyData
@@ -51,21 +51,18 @@ public class ResponseWithHandlebarsXPathTests
var responseBuilder = Response.Create()
.WithHeader("Content-Type", "application/xml")
.WithBody("<response>{{XPath.SelectSingleNode request.body \"/todo-list/todo-item[1]\"}}</response>")
.WithBody("<response>{{XPath.SelectNode request.body \"/todo-list/todo-item[1]/text()\"}}</response>")
.WithTransformer();
// Act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
// Assert
var nav = new XmlDocument { InnerXml = response.Message.BodyData.BodyAsString }.CreateNavigator();
var node = nav.XPath2SelectSingleNode("/response/todo-item");
Check.That(node.Value).Equals("abc");
Check.That(node.GetAttribute("id", "")).Equals("a1");
response.Message.BodyData!.BodyAsString.Should().Be("<response>abc</response>");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_XPath_SelectSingleNode_Text_Request_BodyAsString()
public async Task Response_ProvideResponse_Handlebars_XPath_SelectNode_Text_Request_BodyAsString()
{
// Assign
var body = new BodyData
@@ -82,7 +79,7 @@ public class ResponseWithHandlebarsXPathTests
var responseBuilder = Response.Create()
.WithHeader("Content-Type", "application/xml")
.WithBody("{{XPath.SelectSingleNode request.body \"/todo-list/todo-item[1]/text()\"}}")
.WithBody("{{XPath.SelectNode request.body \"/todo-list/todo-item[1]/text()\"}}")
.WithTransformer();
// Act
@@ -117,13 +114,11 @@ public class ResponseWithHandlebarsXPathTests
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
// Assert
var nav = new XmlDocument { InnerXml = response.Message.BodyData.BodyAsString }.CreateNavigator();
var nodes = nav.XPath2SelectNodes("/response/todo-item");
Check.That(nodes.Count + 1).IsEqualTo(3);
response.Message.BodyData!.BodyAsString.Should().Be("<response>abc,def,xyz</response>");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_XPath_SelectSingleNode_Request_SoapXML_BodyAsString()
public async Task Response_ProvideResponse_Handlebars_XPath_SelectNode_Request_SoapXML_BodyAsString()
{
// Assign
string soap = @"
@@ -168,14 +163,14 @@ public class ResponseWithHandlebarsXPathTests
var responseBuilder = Response.Create()
.WithHeader("Content-Type", "application/xml")
.WithBody("<response>{{XPath.SelectSingleNode request.body \"//*[local-name()='TokenIdLijst']\"}}</response>")
.WithBody("<response>{{XPath.SelectNode request.body \"//*[local-name()='TokenId']/text()\"}}</response>")
.WithTransformer();
// Act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
// Assert
response.Message.BodyData.BodyAsString.Should().Contain("TokenIdLijst").And.Contain("0000083256").And.Contain("0000083259");
response.Message.BodyData!.BodyAsString.Should().Be("<response>0000083256</response>");
}
[Fact]

View File

@@ -783,6 +783,59 @@ public class ResponseWithTransformerTests
response.Message.BodyData.Encoding.Should().Be(enc);
}
#if MIMEKIT
[Theory]
[InlineData(TransformerType.Handlebars)]
// [InlineData(TransformerType.Scriban)]
// [InlineData(TransformerType.ScribanDotLiquid)]
public async Task Response_ProvideResponse_Transformer_WithBodyAsMimeMessage(TransformerType transformerType)
{
// Assign
var multiPart = @"--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/plain; charset=utf-8
This is some plain text
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: text/json; charset=utf-8
{
""Key"": ""Value""
}
--=-5XgmpXt0XOfzdtcgNJc2ZQ==
Content-Type: image/png; name=image.png
Content-Disposition: attachment; filename=image.png
Content-Transfer-Encoding: base64
iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjl
AAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC
--=-5XgmpXt0XOfzdtcgNJc2ZQ==--
";
var bodyData = new BodyData
{
BodyAsString = multiPart,
DetectedBodyType = BodyType.MultiPart
};
var headers = new Dictionary<string, string[]>
{
{ "Content-Type", new[] { @"multipart/mixed; boundary=""=-5XgmpXt0XOfzdtcgNJc2ZQ=="""} }
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData, headers);
var responseBuilder = Response.Create()
.WithBody("{{request.BodyAsMimeMessage.BodyParts.[0].ContentType.MimeType}} {{request.BodyAsMimeMessage.BodyParts.[1].ContentType.MimeType}} {{request.BodyAsMimeMessage.BodyParts.[2].FileName}}")
.WithTransformer(transformerType);
// Act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
// Assert
response.Message.BodyData!.BodyAsString.Should().Be("text/plain text/json image.png");
}
#endif
[Theory]
[InlineData("/wiremock-data/1", "one")]
[InlineData("/wiremock-data/2", "two")]

View File

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

View File

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

View File

@@ -260,7 +260,7 @@ public partial class MappingConverterTests
}
[Fact]
public Task ToMappingModel_WithDelayAsMilliSeconds_ReturnsCorrectModel()
public Task ToMappingModel_WithDelay_ReturnsCorrectModel()
{
// Assign
var delay = 1000;
@@ -343,5 +343,56 @@ public partial class MappingConverterTests
// Verify
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

View File

@@ -56,6 +56,40 @@ public class MatcherMapperTests
models.Should().HaveCount(2);
}
#if MIMEKIT
[Fact]
public void MatcherMapper_Map_MimePartMatcher()
{
// Arrange
var bytes = Convert.FromBase64String("c3RlZg==");
var imagePngContentTypeMatcher = new ContentTypeMatcher("image/png");
var imagePngContentDispositionMatcher = new ExactMatcher("attachment; filename=\"image.png\"");
var imagePngContentTransferEncodingMatcher = new ExactMatcher("base64");
var imagePngContentMatcher = new ExactObjectMatcher(bytes);
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, imagePngContentTypeMatcher, imagePngContentDispositionMatcher, imagePngContentTransferEncodingMatcher, imagePngContentMatcher);
// Act
var model = _sut.Map(imagePngMatcher)!;
// Assert
model.Name.Should().Be(nameof(MimePartMatcher));
model.MatchOperator.Should().BeNull();
model.RejectOnMatch.Should().BeNull();
model.ContentTypeMatcher!.Name.Should().Be(nameof(ContentTypeMatcher));
model.ContentTypeMatcher.Pattern.Should().Be("image/png");
model.ContentDispositionMatcher!.Name.Should().Be(nameof(ExactMatcher));
model.ContentDispositionMatcher.Pattern.Should().Be("attachment; filename=\"image.png\"");
model.ContentTransferEncodingMatcher!.Name.Should().Be(nameof(ExactMatcher));
model.ContentTransferEncodingMatcher.Pattern.Should().Be("base64");
model.ContentMatcher!.Name.Should().Be(nameof(ExactObjectMatcher));
model.ContentMatcher.Pattern.Should().Be(bytes);
}
#endif
[Fact]
public void MatcherMapper_Map_IStringMatcher()
{
@@ -428,4 +462,64 @@ public class MatcherMapperTests
matcher.GetPatterns().Should().Contain("p");
matcher.IgnoreCase.Should().BeTrue();
}
[Fact]
public void MatcherMapper_Map_MatcherModel_NotNullOrEmptyMatcher()
{
// Assign
var model = new MatcherModel
{
Name = "NotNullOrEmptyMatcher",
RejectOnMatch = true
};
// Act
var matcher = _sut.Map(model)!;
// Assert
matcher.Should().BeAssignableTo<NotNullOrEmptyMatcher>();
matcher.MatchBehaviour.Should().Be(MatchBehaviour.RejectOnMatch);
}
#if MIMEKIT
[Fact]
public void MatcherMapper_Map_MatcherModel_MimePartMatcher()
{
// Assign
var model = new MatcherModel
{
Name = "MimePartMatcher",
ContentMatcher = new MatcherModel
{
Name = "ExactMatcher",
Pattern = "x"
},
ContentDispositionMatcher = new MatcherModel
{
Name = "WildcardMatcher",
Pattern = "y"
},
ContentTransferEncodingMatcher = new MatcherModel
{
Name = "RegexMatcher",
Pattern = "z"
},
ContentTypeMatcher = new MatcherModel
{
Name = "ContentTypeMatcher",
Pattern = "text/json"
}
};
// Act
var matcher = (MimePartMatcher)_sut.Map(model)!;
// Assert
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
matcher.ContentMatcher.Should().BeAssignableTo<ExactMatcher>().Which.GetPatterns().Should().ContainSingle("x");
matcher.ContentDispositionMatcher.Should().BeAssignableTo<WildcardMatcher>().Which.GetPatterns().Should().ContainSingle("y");
matcher.ContentTransferEncodingMatcher.Should().BeAssignableTo<RegexMatcher>().Which.GetPatterns().Should().ContainSingle("z");
matcher.ContentTypeMatcher.Should().BeAssignableTo<ContentTypeMatcher>().Which.GetPatterns().Should().ContainSingle("text/json");
}
#endif
}

View File

@@ -24,8 +24,12 @@
<DefineConstants>NETFRAMEWORK</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Util\JsonUtilsTests.cs" />
<Compile Remove="Util\JsonUtilsTests.cs" />
</ItemGroup>
<ItemGroup>
@@ -63,11 +67,8 @@
</PackageReference>
<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="RestEase" Version="1.5.7" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NFluent" Version="2.8.0" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="AnyOf" Version="0.3.0" />
@@ -99,15 +100,14 @@
<ItemGroup Condition="'$(TargetFramework)' != 'net452'">
<PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
<PackageReference Include="JsonConverter.System.Text.Json" Version="0.4.0" />
<!--<PackageReference Include="JsonConverter.NewtonSoft.Json" Version="0.4.0" />-->
</ItemGroup>
<ItemGroup>
<None Update="OpenApiParser\*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="OpenApiParser\*.yml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="responsebody.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
@@ -137,5 +137,4 @@
<ItemGroup>
<Folder Include="Pact\files\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,75 @@
#if MIMEKIT
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using WireMock.Matchers;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
using Xunit;
namespace WireMock.Net.Tests;
public partial class WireMockServerTests
{
[Fact]
public async Task WireMockServer_WithMultiPartBody_Using_MimePartMatchers()
{
// Arrange
var server = WireMockServer.Start();
var textPlainContent = "This is some plain text";
var textPlainContentType = "text/plain";
var textPlainContentTypeMatcher = new ContentTypeMatcher(textPlainContentType);
var textPlainContentMatcher = new ExactMatcher(textPlainContent);
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
var textJson = "{ \"Key\" : \"Value\" }";
var textJsonContentType = "text/json";
var textJsonContentTypeMatcher = new ContentTypeMatcher(textJsonContentType);
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
var jsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
var imagePngBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC");
var imagePngContentMatcher = new ExactObjectMatcher(imagePngBytes);
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, null, null, null, imagePngContentMatcher);
var matchers = new IMatcher[]
{
textPlainMatcher,
jsonMatcher,
imagePngMatcher
};
server
.Given(
Request.Create()
.UsingPost()
.WithPath("/multipart")
.WithMultiPart(matchers))
.RespondWith(Response.Create());
// Act
var formDataContent = new MultipartFormDataContent();
formDataContent.Add(new StringContent(textPlainContent, Encoding.UTF8, textPlainContentType), "text");
formDataContent.Add(new StringContent(textJson, Encoding.UTF8, textJsonContentType), "json");
var fileContent = new ByteArrayContent(imagePngBytes);
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
formDataContent.Add(fileContent, "somefile", "image.png");
var client = server.CreateClient();
var response = await client.PostAsync("/multipart", formDataContent);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
server.Stop();
}
}
#endif

View File

@@ -16,6 +16,7 @@ public partial class WireMockServerTests
[Theory]
[InlineData("SELECT id, value FROM table WHERE id = 1")]
[InlineData("select id, name, value from table where id in (1, 2, 3, 4, 5)")]
[InlineData("1,2,3")]
public async Task WireMockServer_WithParam_QueryParameterMultipleValueSupport_NoComma_Should_Ignore_Comma(string queryValue)
{
// Arrange
@@ -43,4 +44,30 @@ public partial class WireMockServerTests
server.Stop();
}
[Fact]
public async Task WireMockServer_WithParam_MultiValueComma()
{
// Arrange
var queryValue = "1,2,3";
var server = WireMockServer.Start();
server.Given(
Request.Create()
.UsingGet()
.WithPath("/foo")
.WithParam("query", "1", "2", "3")
)
.RespondWith(
Response.Create().WithStatusCode(200)
);
// Act
var requestUri = new Uri($"http://localhost:{server.Port}/foo?query={queryValue}");
var response = await server.CreateClient().GetAsync(requestUri).ConfigureAwait(false);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
server.Stop();
}
}

View File

@@ -0,0 +1,39 @@
namespace MultipartUploader
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

Some files were not shown because too many files have changed in this diff Show More