mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
282281aa7f | ||
|
|
4052a0ef3b | ||
|
|
2ca394b7f6 | ||
|
|
b04000bfdd | ||
|
|
93ab4e1853 | ||
|
|
80b5eaac6e | ||
|
|
a1dc2ba646 | ||
|
|
934c444902 | ||
|
|
83d178bdb5 | ||
|
|
d91b5d5831 | ||
|
|
43b96ce340 | ||
|
|
4d8cf43357 | ||
|
|
328e9090b1 | ||
|
|
a22b3bfbc5 | ||
|
|
29974c7ad4 | ||
|
|
660a09e656 | ||
|
|
fbecd3b119 | ||
|
|
b17840cea9 | ||
|
|
969b0da8e2 | ||
|
|
dc078b57ea | ||
|
|
8140b37095 | ||
|
|
2ad060bbd4 | ||
|
|
d758301e4f | ||
|
|
cee73023c7 | ||
|
|
6f7d2c83f5 | ||
|
|
2fb0f92a2d | ||
|
|
ddf2b49240 | ||
|
|
3617e95db6 | ||
|
|
aa8510fab3 | ||
|
|
e23249c144 | ||
|
|
7a8f4c3630 | ||
|
|
ddcf2b29a3 |
54
CHANGELOG.md
54
CHANGELOG.md
@@ -1,3 +1,53 @@
|
||||
# 1.4.15 (19 May 2021)
|
||||
- [#615](https://github.com/WireMock-Net/WireMock.Net/pull/615) - Add support for multiple webhooks [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#614](https://github.com/WireMock-Net/WireMock.Net/issues/614) - Is it possible to some how send multiple webhooks? [feature]
|
||||
|
||||
# 1.4.14 (11 May 2021)
|
||||
- [#610](https://github.com/WireMock-Net/WireMock.Net/pull/610) - Fix some SonarCloud issues in UnitTests contributed by [StefH](https://github.com/StefH)
|
||||
- [#611](https://github.com/WireMock-Net/WireMock.Net/pull/611) - Allow to add custom service registrations when using ASP.NET Core [feature] contributed by [starkpl](https://github.com/starkpl)
|
||||
- [#612](https://github.com/WireMock-Net/WireMock.Net/pull/612) - Don't run SonarCloud tasks for PullRequests [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.4.13 (26 April 2021)
|
||||
- [#607](https://github.com/WireMock-Net/WireMock.Net/pull/607) - Bump System.Text.Encodings.Web from 4.5.0 to 4.5.1 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#609](https://github.com/WireMock-Net/WireMock.Net/pull/609) - Add possibility to use settings to generate MappingModel models with wildcard path parameters. [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#608](https://github.com/WireMock-Net/WireMock.Net/issues/608) - Import from OpenApi generates model with path parameter narrowed in range (example value=42 instead of '*') [feature]
|
||||
|
||||
# 1.4.12 (22 April 2021)
|
||||
- [#605](https://github.com/WireMock-Net/WireMock.Net/pull/605) - Bump System.Net.Http from 4.3.3 to 4.3.4 in /src/WireMock.Net [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#606](https://github.com/WireMock-Net/WireMock.Net/pull/606) - Bump System.Net.Http from 4.3.3 to 4.3.4 in /examples/WireMock.Net.Service [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
|
||||
# 1.4.11 (18 April 2021)
|
||||
- [#604](https://github.com/WireMock-Net/WireMock.Net/pull/604) - Fix match logic for exact bytearray contributed by [StefH](https://github.com/StefH)
|
||||
- [#601](https://github.com/WireMock-Net/WireMock.Net/issues/601) - Exact byte array request matching fails on specific byte arrays [bug]
|
||||
|
||||
# 1.4.10 (15 April 2021)
|
||||
- [#603](https://github.com/WireMock-Net/WireMock.Net/pull/603) - Fix callback with Headers [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#602](https://github.com/WireMock-Net/WireMock.Net/issues/602) - Header not being returned when set in WithCallback [bug]
|
||||
|
||||
# 1.4.9 (31 March 2021)
|
||||
- [#600](https://github.com/WireMock-Net/WireMock.Net/pull/600) - WithProxy() should save the new mapping [bug] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.4.8 (24 March 2021)
|
||||
- [#591](https://github.com/WireMock-Net/WireMock.Net/pull/591) - Webhook [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#589](https://github.com/WireMock-Net/WireMock.Net/issues/589) - How to send a request to a specific URL after sending response [feature]
|
||||
|
||||
# 1.4.7 (21 March 2021)
|
||||
- [#594](https://github.com/WireMock-Net/WireMock.Net/pull/594) - Add possibility to the WithBody() to use IBodyData [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#595](https://github.com/WireMock-Net/WireMock.Net/pull/595) - Use Handlebars.Net.Helpers Version="2.1.2" [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#597](https://github.com/WireMock-Net/WireMock.Net/pull/597) - Remove 2 second delay from first response and add IPv6 address support [bug, feature] contributed by [benagain](https://github.com/benagain)
|
||||
|
||||
# 1.4.6 (26 February 2021)
|
||||
- [#587](https://github.com/WireMock-Net/WireMock.Net/pull/587) - Fix WithCallback logic when using other fluent builder statements [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#569](https://github.com/WireMock-Net/WireMock.Net/issues/569) - WithCallback circumvent the rest of the builder [bug]
|
||||
|
||||
# 1.4.5 (11 February 2021)
|
||||
- [#585](https://github.com/WireMock-Net/WireMock.Net/pull/585) - Fix response date header [bug] contributed by [wolf8196](https://github.com/wolf8196)
|
||||
|
||||
# 1.4.4 (09 February 2021)
|
||||
- [#581](https://github.com/WireMock-Net/WireMock.Net/pull/581) - Use new Handlebars.Net.Helpers [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#582](https://github.com/WireMock-Net/WireMock.Net/pull/582) - Add Xamarin UI tests [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#568](https://github.com/WireMock-Net/WireMock.Net/issues/568) - [Question] Dates in response templates [feature]
|
||||
|
||||
# 1.4.3 (05 February 2021)
|
||||
- [#570](https://github.com/WireMock-Net/WireMock.Net/pull/570) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.StandAlone.NETCoreApp [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#571](https://github.com/WireMock-Net/WireMock.Net/pull/571) - Bump log4net from 2.0.8 to 2.0.10 in /examples/WireMock.Net.Console.NETCoreApp2 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
@@ -31,7 +81,6 @@
|
||||
- [#549](https://github.com/WireMock-Net/WireMock.Net/issues/549) - WithProxy(...) does not save the mappings to file [bug]
|
||||
|
||||
# 1.3.8 (03 December 2020)
|
||||
- [#539](https://github.com/WireMock-Net/WireMock.Net/pull/539) - Support for partial JSON matching contributed by [gleb-osokin](https://github.com/gleb-osokin)
|
||||
- [#542](https://github.com/WireMock-Net/WireMock.Net/pull/542) - Create dotnet-wiremock tool [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#543](https://github.com/WireMock-Net/WireMock.Net/pull/543) - Add support for .NET 5 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#544](https://github.com/WireMock-Net/WireMock.Net/pull/544) - Use Java 11 in Azure Pipelines (needed for SonarCloud) [feature] contributed by [StefH](https://github.com/StefH)
|
||||
@@ -39,6 +88,9 @@
|
||||
- [#547](https://github.com/WireMock-Net/WireMock.Net/pull/547) - Fix Proxying with SSL and NetCoreApp3.1 [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#524](https://github.com/WireMock-Net/WireMock.Net/issues/524) - Proxying with SSL Not Working in .NET Core 3.1 [bug]
|
||||
|
||||
# 1.3.7 (17 November 2020)
|
||||
- [#539](https://github.com/WireMock-Net/WireMock.Net/pull/539) - Support for partial JSON matching contributed by [gleb-osokin](https://github.com/gleb-osokin)
|
||||
|
||||
# 1.3.6 (10 November 2020)
|
||||
- [#529](https://github.com/WireMock-Net/WireMock.Net/pull/529) - Add assertions for ClientIP, Url and ProxyUrl [feature] contributed by [akamud](https://github.com/akamud)
|
||||
- [#535](https://github.com/WireMock-Net/WireMock.Net/pull/535) - WithCallback should use also use enum HttpStatusCode [bug] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.4.3</VersionPrefix>
|
||||
<VersionPrefix>1.4.16</VersionPrefix>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.4.3
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc --version 1.4.16
|
||||
@@ -36,6 +36,7 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
|
||||
| **WireMock.Net.FluentAssertions** | [](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
|
||||
## Development
|
||||
For the supported frameworks and build information, see [this](https://github.com/WireMock-Net/WireMock.Net/wiki/Development-Information) page.
|
||||
|
||||
@@ -82,8 +82,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Matchers.CShar
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net472.Classic", "examples\WireMock.Net.Console.Net472.Classic\WireMock.Net.Console.Net472.Classic.csproj", "{6580580B-1EFD-4922-B0EC-FF290DB279EE}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.XamarinUI.Tests", "test\WireMock.Net.XamarinUI.Tests\WireMock.Net.XamarinUI.Tests.csproj", "{0DE14F1B-A51E-4B59-A87C-C6012DCD2844}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -206,14 +204,6 @@ Global
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DE14F1B-A51E-4B59-A87C-C6012DCD2844}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DE14F1B-A51E-4B59-A87C-C6012DCD2844}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DE14F1B-A51E-4B59-A87C-C6012DCD2844}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DE14F1B-A51E-4B59-A87C-C6012DCD2844}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B6269AAC-170A-4346-8B9A-444DED3D9A44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B6269AAC-170A-4346-8B9A-444DED3D9A44}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B6269AAC-170A-4346-8B9A-444DED3D9A44}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B6269AAC-170A-4346-8B9A-444DED3D9A44}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -247,9 +237,7 @@ Global
|
||||
{40BF24B5-12E6-4610-9489-138798632E28} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{3F8CF0AE-5F24-4A54-89E7-A3EE829DB5F8} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{B6269AAC-170A-4346-8B9A-444DED3D9A44} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{B6269AAC-170A-4346-8B9A-444DED3D9A44} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{0DE14F1B-A51E-4B59-A87C-C6012DCD2844} = {0BB8B634-407A-4610-A91F-11586990767A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=funcs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Raml/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=randomizer/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stef/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhook/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Webhooks/@EntryIndexedValue">True</s:Boolean>
|
||||
</wpf:ResourceDictionary>
|
||||
@@ -28,6 +28,7 @@ jobs:
|
||||
|
||||
- task: SonarCloudPrepare@1
|
||||
displayName: 'Prepare analysis on SonarCloud'
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
inputs:
|
||||
SonarCloud: SonarCloud
|
||||
organization: wiremock-net
|
||||
@@ -52,9 +53,11 @@ jobs:
|
||||
|
||||
- task: SonarCloudAnalyze@1
|
||||
displayName: 'SonarCloud: Run Code Analysis'
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
|
||||
- task: SonarCloudPublish@1
|
||||
displayName: 'SonarCloud: Publish Quality Gate Result'
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
|
||||
- task: whitesource.ws-bolt.bolt.wss.WhiteSource Bolt@19
|
||||
displayName: 'WhiteSource Bolt'
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace WireMock.Net.ConsoleApplication
|
||||
//},
|
||||
PreWireMockMiddlewareInit = app => { System.Console.WriteLine($"PreWireMockMiddlewareInit : {app.GetType()}"); },
|
||||
PostWireMockMiddlewareInit = app => { System.Console.WriteLine($"PostWireMockMiddlewareInit : {app.GetType()}"); },
|
||||
AdditionalServiceRegistration = services => { System.Console.WriteLine($"AdditionalServiceRegistration : {services.GetType()}"); },
|
||||
Logger = new WireMockConsoleLogger(),
|
||||
|
||||
HandlebarsRegistrationCallback = (handlebarsContext, fileSystemHandler) =>
|
||||
|
||||
@@ -3,9 +3,11 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Net.OpenApiParser.Extensions;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
using WireMock.Net.OpenApiParser.Types;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Net.OpenApiParser.Extensions;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.ConsoleApp
|
||||
{
|
||||
@@ -23,13 +25,18 @@ namespace WireMock.Net.OpenApiParser.ConsoleApp
|
||||
ReadStaticMappings = false,
|
||||
WatchStaticMappings = false,
|
||||
WatchStaticMappingsInSubdirectories = false,
|
||||
Logger = new WireMockConsoleLogger(),
|
||||
Logger = new WireMockConsoleLogger()
|
||||
});
|
||||
Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
|
||||
|
||||
server.SetBasicAuthentication("a", "b");
|
||||
|
||||
server.WithMappingFromOpenApiFile(path, out var diag);
|
||||
var settings = new WireMockOpenApiParserSettings
|
||||
{
|
||||
PathPatternToUse = ExampleValueType.Wildcard
|
||||
};
|
||||
|
||||
server.WithMappingFromOpenApiFile(path, settings, out var diag);
|
||||
|
||||
Console.WriteLine("Press any key to stop the server");
|
||||
System.Console.ReadKey();
|
||||
|
||||
@@ -32,11 +32,8 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Handlebars, Version=1.9.5.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.1.9.5\lib\net452\Handlebars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
|
||||
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin, Version=2.0.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||
@@ -57,6 +54,7 @@
|
||||
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Configuration.Install" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Handlebars.Net" version="1.9.5" targetFramework="net452" />
|
||||
<package id="log4net" version="2.0.10" targetFramework="net452" />
|
||||
<package id="log4net" version="2.0.12" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
|
||||
@@ -12,6 +11,6 @@
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net452" />
|
||||
<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.3" targetFramework="net452" />
|
||||
<package id="System.Net.Http" version="4.3.4" targetFramework="net452" />
|
||||
<package id="XPath2" version="1.1.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -10,6 +10,7 @@ using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Net.StandAlone.NETCoreApp
|
||||
{
|
||||
@@ -34,6 +35,14 @@ namespace WireMock.Net.StandAlone.NETCoreApp
|
||||
|
||||
_server = WireMockServer.Start(settings);
|
||||
|
||||
_server.Given(Request.Create().WithPath("/api/sap")
|
||||
.UsingPost()
|
||||
.WithBody((IBodyData xmlData) => {
|
||||
//xmlData is always null
|
||||
return true;
|
||||
}))
|
||||
.RespondWith(Response.Create().WithStatusCode(System.Net.HttpStatusCode.OK));
|
||||
|
||||
_server
|
||||
.Given(Request.Create()
|
||||
.UsingAnyMethod())
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"WireMock.Net.StandAlone.NETCoreApp": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "--Urls https://localhost:10080 --WireMockLogger WireMockConsoleLogger"
|
||||
"commandLineArgs": "--Urls http://localhost:9091 --WireMockLogger WireMockConsoleLogger"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,8 +39,8 @@
|
||||
<StartupObject>WireMock.Net.StandAlone.Net452.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll</HintPath>
|
||||
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.4.0.0\lib\net451\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||
@@ -49,12 +49,14 @@
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.6\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="log4net" version="2.0.10" targetFramework="net452" />
|
||||
<package id="log4net" version="2.0.12" 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="11.0.2" targetFramework="net452" />
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
|
||||
<package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net461" />
|
||||
<package id="System.Security.Principal.Windows" version="4.5.1" targetFramework="net461" />
|
||||
<package id="System.Text.Encodings.Web" version="4.5.0" targetFramework="net461" />
|
||||
<package id="System.Text.Encodings.Web" version="4.5.1" targetFramework="net461" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net461" />
|
||||
<package id="XPath2" version="1.1.0" targetFramework="net461" />
|
||||
</packages>
|
||||
@@ -52,5 +52,15 @@ namespace WireMock.Admin.Mappings
|
||||
/// Saves this mapping as a static mapping file.
|
||||
/// </summary>
|
||||
public bool? SaveToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhook.
|
||||
/// </summary>
|
||||
public WebhookModel Webhook { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
public WebhookModel[] Webhooks { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Admin.Mappings
|
||||
{
|
||||
|
||||
13
src/WireMock.Net.Abstractions/Admin/Mappings/WebhookModel.cs
Normal file
13
src/WireMock.Net.Abstractions/Admin/Mappings/WebhookModel.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace WireMock.Admin.Mappings
|
||||
{
|
||||
/// <summary>
|
||||
/// The Webhook
|
||||
/// </summary>
|
||||
public class WebhookModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The Webhook Request.
|
||||
/// </summary>
|
||||
public WebhookRequestModel Request { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Admin.Mappings
|
||||
{
|
||||
/// <summary>
|
||||
/// RequestModel
|
||||
/// </summary>
|
||||
public class WebhookRequestModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the Url.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The methods
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the headers.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body.
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body (as JSON object).
|
||||
/// </summary>
|
||||
public object BodyAsJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use ResponseMessage Transformer.
|
||||
/// </summary>
|
||||
public bool? UseTransformer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the transformer.
|
||||
/// </summary>
|
||||
public string TransformerType { get; set; }
|
||||
}
|
||||
}
|
||||
13
src/WireMock.Net.Abstractions/Models/IWebhook.cs
Normal file
13
src/WireMock.Net.Abstractions/Models/IWebhook.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace WireMock.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// IWebhook
|
||||
/// </summary>
|
||||
public interface IWebhook
|
||||
{
|
||||
/// <summary>
|
||||
/// Request
|
||||
/// </summary>
|
||||
IWebhookRequest Request { get; set; }
|
||||
}
|
||||
}
|
||||
42
src/WireMock.Net.Abstractions/Models/IWebhookRequest.cs
Normal file
42
src/WireMock.Net.Abstractions/Models/IWebhookRequest.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// IWebhookRequest
|
||||
/// </summary>
|
||||
public interface IWebhookRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// The Webhook Url.
|
||||
/// </summary>
|
||||
string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The method to use.
|
||||
/// </summary>
|
||||
string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Headers to send.
|
||||
/// </summary>
|
||||
IDictionary<string, WireMockList<string>> Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body to send.
|
||||
/// </summary>
|
||||
IBodyData BodyData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Use Transformer.
|
||||
/// </summary>
|
||||
bool? UseTransformer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The transformer type.
|
||||
/// </summary>
|
||||
TransformerType TransformerType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,19 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.Readers;
|
||||
using SharpYaml.Model;
|
||||
using Stef.Validation;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
using WireMock.Server;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Some extension methods for <see cref="IWireMockServer"/>.
|
||||
/// </summary>
|
||||
public static class WireMockServerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
@@ -15,18 +22,26 @@ namespace WireMock.Net.OpenApiParser.Extensions
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
|
||||
[PublicAPI]
|
||||
public static IWireMockServer WithMappingFromOpenApiFile(this IWireMockServer server, string path, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
if (server == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(server));
|
||||
}
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(path));
|
||||
}
|
||||
return WithMappingFromOpenApiFile(server, path, null, out diagnostic);
|
||||
}
|
||||
|
||||
var mappings = new WireMockOpenApiParser().FromFile(path, out diagnostic);
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2 or V3 file.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
[PublicAPI]
|
||||
public static IWireMockServer WithMappingFromOpenApiFile(this IWireMockServer server, string path, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
Guard.NotNull(server, nameof(server));
|
||||
Guard.NotNullOrEmpty(path, nameof(path));
|
||||
|
||||
var mappings = new WireMockOpenApiParser().FromFile(path, settings, out diagnostic);
|
||||
|
||||
return server.WithMapping(mappings.ToArray());
|
||||
}
|
||||
@@ -37,9 +52,27 @@ namespace WireMock.Net.OpenApiParser.Extensions
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
|
||||
[PublicAPI]
|
||||
public static IWireMockServer WithMappingFromOpenApiStream(this IWireMockServer server, Stream stream, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
var mappings = new WireMockOpenApiParser().FromStream(stream, out diagnostic);
|
||||
return WithMappingFromOpenApiStream(server, stream, null, out diagnostic);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2 or V3 stream.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
/// <param name="diagnostic">Returns diagnostic object containing errors detected during parsing</param>
|
||||
[PublicAPI]
|
||||
public static IWireMockServer WithMappingFromOpenApiStream(this IWireMockServer server, Stream stream, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
Guard.NotNull(server, nameof(server));
|
||||
Guard.NotNull(stream, nameof(stream));
|
||||
Guard.NotNull(settings, nameof(settings));
|
||||
|
||||
var mappings = new WireMockOpenApiParser().FromStream(stream, settings, out diagnostic);
|
||||
|
||||
return server.WithMapping(mappings.ToArray());
|
||||
}
|
||||
@@ -49,9 +82,14 @@ namespace WireMock.Net.OpenApiParser.Extensions
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="document">The OpenAPI document to use as mappings.</param>
|
||||
public static IWireMockServer WithMappingFromOpenApiDocument(this IWireMockServer server, OpenApiDocument document)
|
||||
/// <param name="settings">Additional settings [optional]</param>
|
||||
[PublicAPI]
|
||||
public static IWireMockServer WithMappingFromOpenApiDocument(this IWireMockServer server, OpenApiDocument document, WireMockOpenApiParserSettings settings = null)
|
||||
{
|
||||
var mappings = new WireMockOpenApiParser().FromDocument(document);
|
||||
Guard.NotNull(server, nameof(server));
|
||||
Guard.NotNull(document, nameof(document));
|
||||
|
||||
var mappings = new WireMockOpenApiParser().FromDocument(document, settings);
|
||||
|
||||
return server.WithMapping(mappings.ToArray());
|
||||
}
|
||||
|
||||
@@ -1,37 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.Readers;
|
||||
using WireMock.Admin.Mappings;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse a OpenApi/Swagger/V2/V3 or Raml to WireMock MappingModels.
|
||||
/// </summary>
|
||||
public interface IWireMockOpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from an <seealso cref="OpenApiDocument"/>.
|
||||
/// </summary>
|
||||
/// <param name="document">The source OpenApiDocument</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromDocument(OpenApiDocument document);
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromStream(Stream stream, out OpenApiDiagnostic diagnostic);
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.Readers;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse a OpenApi/Swagger/V2/V3 or Raml to WireMock MappingModels.
|
||||
/// </summary>
|
||||
public interface IWireMockOpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from a file-path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3 or Raml file.</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic);
|
||||
}
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic);
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from a file-path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3 or Raml file.</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromFile(string path, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic);
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from an <seealso cref="OpenApiDocument"/>.
|
||||
/// </summary>
|
||||
/// <param name="document">The source OpenApiDocument</param>
|
||||
/// <param name="settings">Additional settings [optional]</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromDocument(OpenApiDocument document, WireMockOpenApiParserSettings settings = null);
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromStream(Stream stream, out OpenApiDiagnostic diagnostic);
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IEnumerable{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
/// <returns>MappingModel</returns>
|
||||
IEnumerable<MappingModel> FromStream(Stream stream, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic);
|
||||
}
|
||||
}
|
||||
276
src/WireMock.Net.OpenApiParser/Mappers/OpenApiPathsMapper.cs
Normal file
276
src/WireMock.Net.OpenApiParser/Mappers/OpenApiPathsMapper.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.OpenApi;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.Writers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Net.OpenApiParser.Extensions;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
using WireMock.Net.OpenApiParser.Types;
|
||||
using WireMock.Net.OpenApiParser.Utils;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Mappers
|
||||
{
|
||||
internal class OpenApiPathsMapper
|
||||
{
|
||||
private readonly WireMockOpenApiParserSettings _settings;
|
||||
private readonly ExampleValueGenerator _exampleValueGenerator;
|
||||
|
||||
public OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
_exampleValueGenerator = new ExampleValueGenerator(settings);
|
||||
}
|
||||
|
||||
public IEnumerable<MappingModel> ToMappingModels(OpenApiPaths paths)
|
||||
{
|
||||
return paths.Select(p => MapPath(p.Key, p.Value)).SelectMany(x => x);
|
||||
}
|
||||
|
||||
private IEnumerable<MappingModel> MapPaths(OpenApiPaths paths)
|
||||
{
|
||||
return paths.Select(p => MapPath(p.Key, p.Value)).SelectMany(x => x);
|
||||
}
|
||||
|
||||
private IEnumerable<MappingModel> MapPath(string path, OpenApiPathItem pathItem)
|
||||
{
|
||||
return pathItem.Operations.Select(o => MapOperationToMappingModel(path, o.Key.ToString().ToUpperInvariant(), o.Value));
|
||||
}
|
||||
|
||||
private MappingModel MapOperationToMappingModel(string path, string httpMethod, OpenApiOperation operation)
|
||||
{
|
||||
var queryParameters = operation.Parameters.Where(p => p.In == ParameterLocation.Query);
|
||||
var pathParameters = operation.Parameters.Where(p => p.In == ParameterLocation.Path);
|
||||
var response = operation.Responses.FirstOrDefault();
|
||||
|
||||
TryGetContent(response.Value?.Content, out OpenApiMediaType responseContent, out string responseContentType);
|
||||
var responseSchema = response.Value?.Content?.FirstOrDefault().Value?.Schema;
|
||||
var responseExample = responseContent?.Example;
|
||||
|
||||
var body = responseExample != null ? MapOpenApiAnyToJToken(responseExample) : MapSchemaToObject(responseSchema);
|
||||
|
||||
if (int.TryParse(response.Key, out var httpStatusCode))
|
||||
{
|
||||
httpStatusCode = 200;
|
||||
}
|
||||
|
||||
return new MappingModel
|
||||
{
|
||||
Guid = Guid.NewGuid(),
|
||||
Request = new RequestModel
|
||||
{
|
||||
Methods = new[] { httpMethod },
|
||||
Path = MapPathWithParameters(path, pathParameters),
|
||||
Params = MapQueryParameters(queryParameters)
|
||||
},
|
||||
Response = new ResponseModel
|
||||
{
|
||||
StatusCode = httpStatusCode,
|
||||
Headers = MapHeaders(responseContentType, response.Value?.Headers),
|
||||
BodyAsJson = body
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private bool TryGetContent(IDictionary<string, OpenApiMediaType> contents, out OpenApiMediaType openApiMediaType, out string contentType)
|
||||
{
|
||||
openApiMediaType = null;
|
||||
contentType = null;
|
||||
|
||||
if (contents == null || contents.Values.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contents.TryGetValue("application/json", out var content))
|
||||
{
|
||||
openApiMediaType = content;
|
||||
contentType = "application/json";
|
||||
}
|
||||
else
|
||||
{
|
||||
var first = contents.FirstOrDefault();
|
||||
openApiMediaType = first.Value;
|
||||
contentType = first.Key;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private object MapSchemaToObject(OpenApiSchema schema, string name = null)
|
||||
{
|
||||
if (schema == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (schema.GetSchemaType())
|
||||
{
|
||||
case SchemaType.Array:
|
||||
var jArray = new JArray();
|
||||
for (int i = 0; i < _settings.NumberOfArrayItems; i++)
|
||||
{
|
||||
if (schema.Items.Properties.Count > 0)
|
||||
{
|
||||
var arrayItem = new JObject();
|
||||
foreach (var property in schema.Items.Properties)
|
||||
{
|
||||
var objectValue = MapSchemaToObject(property.Value, property.Key);
|
||||
if (objectValue is JProperty jp)
|
||||
{
|
||||
arrayItem.Add(jp);
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayItem.Add(new JProperty(property.Key, objectValue));
|
||||
}
|
||||
}
|
||||
|
||||
jArray.Add(arrayItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
jArray.Add(MapSchemaToObject(schema.Items, name));
|
||||
}
|
||||
}
|
||||
|
||||
return jArray;
|
||||
|
||||
case SchemaType.Boolean:
|
||||
case SchemaType.Integer:
|
||||
case SchemaType.Number:
|
||||
case SchemaType.String:
|
||||
return _exampleValueGenerator.GetExampleValue(schema);
|
||||
|
||||
case SchemaType.Object:
|
||||
var propertyAsJObject = new JObject();
|
||||
foreach (var schemaProperty in schema.Properties)
|
||||
{
|
||||
string propertyName = schemaProperty.Key;
|
||||
var openApiSchema = schemaProperty.Value;
|
||||
if (openApiSchema.GetSchemaType() == SchemaType.Object)
|
||||
{
|
||||
var mapped = MapSchemaToObject(schemaProperty.Value, schemaProperty.Key);
|
||||
if (mapped is JProperty jp)
|
||||
{
|
||||
propertyAsJObject.Add(jp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool propertyIsNullable = openApiSchema.Nullable || (openApiSchema.TryGetXNullable(out bool x) && x);
|
||||
|
||||
propertyAsJObject.Add(new JProperty(propertyName, _exampleValueGenerator.GetExampleValue(openApiSchema)));
|
||||
}
|
||||
}
|
||||
|
||||
return name != null ? new JProperty(name, propertyAsJObject) : (JToken)propertyAsJObject;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string MapPathWithParameters(string path, IEnumerable<OpenApiParameter> parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
string newPath = path;
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
newPath = newPath.Replace($"{{{parameter.Name}}}", GetExampleValue(parameter.Schema, _settings.PathPatternToUse));
|
||||
}
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
private JToken MapOpenApiAnyToJToken(IOpenApiAny any)
|
||||
{
|
||||
if (any == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using var outputString = new StringWriter();
|
||||
var writer = new OpenApiJsonWriter(outputString);
|
||||
any.Write(writer, OpenApiSpecVersion.OpenApi3_0);
|
||||
|
||||
return JObject.Parse(outputString.ToString());
|
||||
}
|
||||
|
||||
private IDictionary<string, object> MapHeaders(string responseContentType, IDictionary<string, OpenApiHeader> headers)
|
||||
{
|
||||
var mappedHeaders = headers.ToDictionary(
|
||||
item => item.Key,
|
||||
item => GetExampleValue(null, _settings.HeaderPatternToUse) as object
|
||||
);
|
||||
|
||||
if (!string.IsNullOrEmpty(responseContentType))
|
||||
{
|
||||
if (!mappedHeaders.ContainsKey("Content-Type"))
|
||||
{
|
||||
mappedHeaders.Add("Content-Type", responseContentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
mappedHeaders["Content-Type"] = responseContentType;
|
||||
}
|
||||
}
|
||||
|
||||
return mappedHeaders.Keys.Any() ? mappedHeaders : null;
|
||||
}
|
||||
|
||||
private IList<ParamModel> MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters)
|
||||
{
|
||||
var list = queryParameters
|
||||
.Select(qp => new ParamModel
|
||||
{
|
||||
Name = qp.Name,
|
||||
Matchers = new[]
|
||||
{
|
||||
new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Pattern = GetDefaultValueAsStringForSchemaType(qp.Schema)
|
||||
}
|
||||
}
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return list.Any() ? list : null;
|
||||
}
|
||||
|
||||
private string GetDefaultValueAsStringForSchemaType(OpenApiSchema schema)
|
||||
{
|
||||
var value = _exampleValueGenerator.GetExampleValue(schema);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case string valueAsString:
|
||||
return valueAsString;
|
||||
|
||||
default:
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetExampleValue(OpenApiSchema schema, ExampleValueType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ExampleValueType.Value:
|
||||
return GetDefaultValueAsStringForSchemaType(schema);
|
||||
|
||||
default:
|
||||
return "*";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// A class defining the example values to use for the different types.
|
||||
/// </summary>
|
||||
public class WireMockOpenApiParserExampleValues
|
||||
{
|
||||
#pragma warning disable 1591
|
||||
public bool Boolean { get; set; } = true;
|
||||
|
||||
public int Integer { get; set; } = 42;
|
||||
|
||||
public float Float { get; set; } = 4.2f;
|
||||
|
||||
public double Double { get; set; } = 4.2d;
|
||||
|
||||
public Func<DateTime> Date { get; set; } = () => System.DateTime.UtcNow.Date;
|
||||
|
||||
public Func<DateTime> DateTime { get; set; } = () => System.DateTime.UtcNow;
|
||||
|
||||
public byte[] Bytes { get; set; } = { 48, 49, 50 };
|
||||
|
||||
public object Object { get; set; } = "example-object";
|
||||
|
||||
public string String { get; set; } = "example-string";
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using WireMock.Net.OpenApiParser.Types;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// The WireMockOpenApiParser Settings
|
||||
/// </summary>
|
||||
public class WireMockOpenApiParserSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of array items to generate (default is 3).
|
||||
/// </summary>
|
||||
public int NumberOfArrayItems { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// The example value type to use when generating a Path
|
||||
/// </summary>
|
||||
public ExampleValueType PathPatternToUse { get; set; } = ExampleValueType.Value;
|
||||
|
||||
/// <summary>
|
||||
/// The example value type to use when generating a Header
|
||||
/// </summary>
|
||||
public ExampleValueType HeaderPatternToUse { get; set; } = ExampleValueType.Value;
|
||||
|
||||
/// <summary>
|
||||
/// The example values to use
|
||||
/// </summary>
|
||||
public WireMockOpenApiParserExampleValues ExampleValues { get; } = new WireMockOpenApiParserExampleValues();
|
||||
}
|
||||
}
|
||||
18
src/WireMock.Net.OpenApiParser/Types/ExampleValueType.cs
Normal file
18
src/WireMock.Net.OpenApiParser/Types/ExampleValueType.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace WireMock.Net.OpenApiParser.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// The example value to use
|
||||
/// </summary>
|
||||
public enum ExampleValueType
|
||||
{
|
||||
/// <summary>
|
||||
/// Use a generated example value based on the SchemaType (default).
|
||||
/// </summary>
|
||||
Value,
|
||||
|
||||
/// <summary>
|
||||
/// Just use a Wildcard (*) character.
|
||||
/// </summary>
|
||||
Wildcard
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,57 @@
|
||||
using System;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using WireMock.Net.OpenApiParser.Extensions;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
using WireMock.Net.OpenApiParser.Types;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Utils
|
||||
{
|
||||
internal static class ExampleValueGenerator
|
||||
internal class ExampleValueGenerator
|
||||
{
|
||||
public static object GetExampleValue(OpenApiSchema schema)
|
||||
private readonly WireMockOpenApiParserSettings _settings;
|
||||
|
||||
public ExampleValueGenerator(WireMockOpenApiParserSettings settings)
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
public object GetExampleValue(OpenApiSchema schema)
|
||||
{
|
||||
switch (schema?.GetSchemaType())
|
||||
{
|
||||
case SchemaType.Boolean:
|
||||
return true;
|
||||
return _settings.ExampleValues.Boolean;
|
||||
|
||||
case SchemaType.Integer:
|
||||
return 42;
|
||||
return _settings.ExampleValues.Integer;
|
||||
|
||||
case SchemaType.Number:
|
||||
switch (schema?.GetSchemaFormat())
|
||||
{
|
||||
case SchemaFormat.Float:
|
||||
return 4.2f;
|
||||
return _settings.ExampleValues.Float;
|
||||
|
||||
default:
|
||||
return 4.2d;
|
||||
return _settings.ExampleValues.Double;
|
||||
}
|
||||
|
||||
default:
|
||||
switch (schema?.GetSchemaFormat())
|
||||
{
|
||||
case SchemaFormat.Date:
|
||||
return DateTimeUtils.ToRfc3339Date(DateTime.UtcNow);
|
||||
return DateTimeUtils.ToRfc3339Date(_settings.ExampleValues.Date());
|
||||
|
||||
case SchemaFormat.DateTime:
|
||||
return DateTimeUtils.ToRfc3339DateTime(DateTime.UtcNow);
|
||||
return DateTimeUtils.ToRfc3339DateTime(_settings.ExampleValues.DateTime());
|
||||
|
||||
case SchemaFormat.Byte:
|
||||
return new byte[] { 48, 49, 50 };
|
||||
return _settings.ExampleValues.Bytes;
|
||||
|
||||
case SchemaFormat.Binary:
|
||||
return "example-object";
|
||||
return _settings.ExampleValues.Object;
|
||||
|
||||
default:
|
||||
return "example-string";
|
||||
return _settings.ExampleValues.String;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
@@ -24,14 +25,11 @@
|
||||
<PackageReference Include="RamlToOpenApiConverter" Version="0.1.1" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Options\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,34 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.OpenApi.Readers;
|
||||
using Microsoft.OpenApi.Writers;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using RamlToOpenApiConverter;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Net.OpenApiParser.Extensions;
|
||||
using WireMock.Net.OpenApiParser.Types;
|
||||
using WireMock.Net.OpenApiParser.Utils;
|
||||
using WireMock.Net.OpenApiParser.Mappers;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse a OpenApi/Swagger/V2/V3 or Raml to WireMock MappingModels.
|
||||
/// Parse a OpenApi/Swagger/V2/V3 or Raml to WireMock.Net MappingModels.
|
||||
/// </summary>
|
||||
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
{
|
||||
private const int ArrayItems = 3;
|
||||
|
||||
private readonly OpenApiStreamReader _reader = new OpenApiStreamReader();
|
||||
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromFile" />
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromFile(string, out OpenApiDiagnostic)" />
|
||||
[PublicAPI]
|
||||
public IEnumerable<MappingModel> FromFile(string path, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return FromFile(path, new WireMockOpenApiParserSettings(), out diagnostic);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromFile(string, WireMockOpenApiParserSettings, out OpenApiDiagnostic)" />
|
||||
[PublicAPI]
|
||||
public IEnumerable<MappingModel> FromFile(string path, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
OpenApiDocument document;
|
||||
if (Path.GetExtension(path).EndsWith("raml", StringComparison.OrdinalIgnoreCase))
|
||||
@@ -42,248 +41,28 @@ namespace WireMock.Net.OpenApiParser
|
||||
document = reader.Read(File.OpenRead(path), out diagnostic);
|
||||
}
|
||||
|
||||
return FromDocument(document);
|
||||
return FromDocument(document, settings);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromStream" />
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromStream(Stream, out OpenApiDiagnostic)" />
|
||||
[PublicAPI]
|
||||
public IEnumerable<MappingModel> FromStream(Stream stream, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return FromDocument(_reader.Read(stream, out diagnostic));
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromDocument" />
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromStream(Stream, WireMockOpenApiParserSettings, out OpenApiDiagnostic)" />
|
||||
[PublicAPI]
|
||||
public IEnumerable<MappingModel> FromDocument(OpenApiDocument openApiDocument)
|
||||
public IEnumerable<MappingModel> FromStream(Stream stream, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return MapPaths(openApiDocument.Paths);
|
||||
return FromDocument(_reader.Read(stream, out diagnostic), settings);
|
||||
}
|
||||
|
||||
private static IEnumerable<MappingModel> MapPaths(OpenApiPaths paths)
|
||||
/// <inheritdoc cref="IWireMockOpenApiParser.FromDocument(OpenApiDocument, WireMockOpenApiParserSettings)" />
|
||||
[PublicAPI]
|
||||
public IEnumerable<MappingModel> FromDocument(OpenApiDocument openApiDocument, WireMockOpenApiParserSettings settings = null)
|
||||
{
|
||||
return paths.Select(p => MapPath(p.Key, p.Value)).SelectMany(x => x);
|
||||
}
|
||||
|
||||
private static IEnumerable<MappingModel> MapPath(string path, OpenApiPathItem pathItem)
|
||||
{
|
||||
return pathItem.Operations.Select(o => MapOperationToMappingModel(path, o.Key.ToString().ToUpperInvariant(), o.Value));
|
||||
}
|
||||
|
||||
private static MappingModel MapOperationToMappingModel(string path, string httpMethod, OpenApiOperation operation)
|
||||
{
|
||||
var queryParameters = operation.Parameters.Where(p => p.In == ParameterLocation.Query);
|
||||
var pathParameters = operation.Parameters.Where(p => p.In == ParameterLocation.Path);
|
||||
var response = operation.Responses.FirstOrDefault();
|
||||
TryGetContent(response.Value?.Content, out OpenApiMediaType responseContent, out string responseContentType);
|
||||
var responseSchema = response.Value?.Content?.FirstOrDefault().Value?.Schema;
|
||||
var responseExample = responseContent?.Example;
|
||||
|
||||
var body = responseExample != null ? MapOpenApiAnyToJToken(responseExample) : MapSchemaToObject(responseSchema);
|
||||
|
||||
if (int.TryParse(response.Key, out var httpStatusCode))
|
||||
{
|
||||
httpStatusCode = 200;
|
||||
}
|
||||
|
||||
return new MappingModel
|
||||
{
|
||||
Guid = Guid.NewGuid(),
|
||||
Request = new RequestModel
|
||||
{
|
||||
Methods = new[] { httpMethod },
|
||||
Path = MapPathWithParameters(path, pathParameters),
|
||||
Params = MapQueryParameters(queryParameters)
|
||||
},
|
||||
Response = new ResponseModel
|
||||
{
|
||||
StatusCode = httpStatusCode,
|
||||
Headers = MapHeaders(responseContentType, response.Value?.Headers),
|
||||
BodyAsJson = body
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static bool TryGetContent(IDictionary<string, OpenApiMediaType> contents, out OpenApiMediaType openApiMediaType, out string contentType)
|
||||
{
|
||||
openApiMediaType = null;
|
||||
contentType = null;
|
||||
|
||||
if (contents == null || contents.Values.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contents.TryGetValue("application/json", out var content))
|
||||
{
|
||||
openApiMediaType = content;
|
||||
contentType = "application/json";
|
||||
}
|
||||
else
|
||||
{
|
||||
var first = contents.FirstOrDefault();
|
||||
openApiMediaType = first.Value;
|
||||
contentType = first.Key;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static object MapSchemaToObject(OpenApiSchema schema, string name = null)
|
||||
{
|
||||
if (schema == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (schema.GetSchemaType())
|
||||
{
|
||||
case SchemaType.Array:
|
||||
var jArray = new JArray();
|
||||
for (int i = 0; i < ArrayItems; i++)
|
||||
{
|
||||
if (schema.Items.Properties.Count > 0)
|
||||
{
|
||||
var arrayItem = new JObject();
|
||||
foreach (var property in schema.Items.Properties)
|
||||
{
|
||||
var objectValue = MapSchemaToObject(property.Value, property.Key);
|
||||
if (objectValue is JProperty jp)
|
||||
{
|
||||
arrayItem.Add(jp);
|
||||
}
|
||||
else
|
||||
{
|
||||
arrayItem.Add(new JProperty(property.Key, objectValue));
|
||||
}
|
||||
}
|
||||
|
||||
jArray.Add(arrayItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
jArray.Add(MapSchemaToObject(schema.Items, name));
|
||||
}
|
||||
}
|
||||
|
||||
return jArray;
|
||||
|
||||
case SchemaType.Boolean:
|
||||
case SchemaType.Integer:
|
||||
case SchemaType.Number:
|
||||
case SchemaType.String:
|
||||
return ExampleValueGenerator.GetExampleValue(schema);
|
||||
|
||||
case SchemaType.Object:
|
||||
var propertyAsJObject = new JObject();
|
||||
foreach (var schemaProperty in schema.Properties)
|
||||
{
|
||||
string propertyName = schemaProperty.Key;
|
||||
var openApiSchema = schemaProperty.Value;
|
||||
if (openApiSchema.GetSchemaType() == SchemaType.Object)
|
||||
{
|
||||
var mapped = MapSchemaToObject(schemaProperty.Value, schemaProperty.Key);
|
||||
if (mapped is JProperty jp)
|
||||
{
|
||||
propertyAsJObject.Add(jp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool propertyIsNullable = openApiSchema.Nullable || (openApiSchema.TryGetXNullable(out bool x) && x);
|
||||
|
||||
propertyAsJObject.Add(new JProperty(propertyName, ExampleValueGenerator.GetExampleValue(openApiSchema)));
|
||||
}
|
||||
}
|
||||
|
||||
return name != null ? new JProperty(name, propertyAsJObject) : (JToken)propertyAsJObject;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string MapPathWithParameters(string path, IEnumerable<OpenApiParameter> parameters)
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
string newPath = path;
|
||||
foreach (var parameter in parameters)
|
||||
{
|
||||
newPath = newPath.Replace($"{{{parameter.Name}}}", ExampleValueGenerator.GetExampleValue(parameter.Schema).ToString());
|
||||
}
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
private static JToken MapOpenApiAnyToJToken(IOpenApiAny any)
|
||||
{
|
||||
if (any == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var outputString = new StringWriter())
|
||||
{
|
||||
var writer = new OpenApiJsonWriter(outputString);
|
||||
any.Write(writer, OpenApiSpecVersion.OpenApi3_0);
|
||||
|
||||
return JObject.Parse(outputString.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static IDictionary<string, object> MapHeaders(string responseContentType, IDictionary<string, OpenApiHeader> headers)
|
||||
{
|
||||
var mappedHeaders = headers.ToDictionary(item => item.Key, item => ExampleValueGenerator.GetExampleValue(null));
|
||||
if (!string.IsNullOrEmpty(responseContentType))
|
||||
{
|
||||
if (!mappedHeaders.ContainsKey("Content-Type"))
|
||||
{
|
||||
mappedHeaders.Add("Content-Type", responseContentType);
|
||||
}
|
||||
else
|
||||
{
|
||||
mappedHeaders["Content-Type"] = responseContentType;
|
||||
}
|
||||
}
|
||||
|
||||
return mappedHeaders.Keys.Any() ? mappedHeaders : null;
|
||||
}
|
||||
|
||||
private static IList<ParamModel> MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters)
|
||||
{
|
||||
var list = queryParameters
|
||||
.Select(qp => new ParamModel
|
||||
{
|
||||
Name = qp.Name,
|
||||
Matchers = new[]
|
||||
{
|
||||
new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Pattern = GetDefaultValueAsStringForSchemaType(qp.Schema)
|
||||
}
|
||||
}
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return list.Any() ? list : null;
|
||||
}
|
||||
|
||||
private static string GetDefaultValueAsStringForSchemaType(OpenApiSchema schema)
|
||||
{
|
||||
var value = ExampleValueGenerator.GetExampleValue(schema);
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case string valueAsString:
|
||||
return valueAsString;
|
||||
|
||||
default:
|
||||
return value.ToString();
|
||||
}
|
||||
return new OpenApiPathsMapper(settings).ToMappingModels(openApiDocument.Paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace WireMock.Http
|
||||
{
|
||||
internal static class HttpClientBuilder
|
||||
{
|
||||
public static HttpClient Build(IProxyAndRecordSettings settings)
|
||||
public static HttpClient Build(IHttpClientSettings settings)
|
||||
{
|
||||
#if NETSTANDARD || NETCOREAPP3_1 || NET5_0
|
||||
var handler = new HttpClientHandler
|
||||
|
||||
85
src/WireMock.Net/Http/WebhookSender.cs
Normal file
85
src/WireMock.Net/Http/WebhookSender.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Models;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Transformers;
|
||||
using WireMock.Transformers.Handlebars;
|
||||
using WireMock.Transformers.Scriban;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Http
|
||||
{
|
||||
internal class WebhookSender
|
||||
{
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
|
||||
public WebhookSender(IWireMockServerSettings settings)
|
||||
{
|
||||
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||
}
|
||||
|
||||
public Task<HttpResponseMessage> SendAsync([NotNull] HttpClient client, [NotNull] IWebhookRequest request, [NotNull] RequestMessage originalRequestMessage, [NotNull] ResponseMessage originalResponseMessage)
|
||||
{
|
||||
Check.NotNull(client, nameof(client));
|
||||
Check.NotNull(request, nameof(request));
|
||||
Check.NotNull(originalRequestMessage, nameof(originalRequestMessage));
|
||||
Check.NotNull(originalResponseMessage, nameof(originalResponseMessage));
|
||||
|
||||
IBodyData bodyData;
|
||||
IDictionary<string, WireMockList<string>> headers;
|
||||
if (request.UseTransformer == true)
|
||||
{
|
||||
ITransformer responseMessageTransformer;
|
||||
switch (request.TransformerType)
|
||||
{
|
||||
case TransformerType.Handlebars:
|
||||
var factoryHandlebars = new HandlebarsContextFactory(_settings.FileSystemHandler, _settings.HandlebarsRegistrationCallback);
|
||||
responseMessageTransformer = new Transformer(factoryHandlebars);
|
||||
break;
|
||||
|
||||
case TransformerType.Scriban:
|
||||
case TransformerType.ScribanDotLiquid:
|
||||
var factoryDotLiquid = new ScribanContextFactory(_settings.FileSystemHandler, request.TransformerType);
|
||||
responseMessageTransformer = new Transformer(factoryDotLiquid);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotImplementedException($"TransformerType '{request.TransformerType}' is not supported.");
|
||||
}
|
||||
|
||||
(bodyData, headers) = responseMessageTransformer.Transform(originalRequestMessage, originalResponseMessage, request.BodyData, request.Headers);
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyData = request.BodyData;
|
||||
headers = request.Headers;
|
||||
}
|
||||
|
||||
// Create RequestMessage
|
||||
var requestMessage = new RequestMessage(
|
||||
new UrlDetails(request.Url),
|
||||
request.Method,
|
||||
ClientIp,
|
||||
bodyData,
|
||||
headers?.ToDictionary(x => x.Key, x => x.Value.ToArray())
|
||||
)
|
||||
{
|
||||
DateTime = DateTime.UtcNow
|
||||
};
|
||||
|
||||
// Create HttpRequestMessage
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, request.Url);
|
||||
|
||||
// Call the URL
|
||||
return client.SendAsync(httpRequestMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
@@ -93,12 +94,17 @@ namespace WireMock
|
||||
/// </value>
|
||||
bool LogMapping { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The Webhooks.
|
||||
/// </summary>
|
||||
IWebhook[] Webhooks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ProvideResponseAsync
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/>.</returns>
|
||||
Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage);
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the RequestMatchResult based on the RequestMessage.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
@@ -54,6 +55,9 @@ namespace WireMock
|
||||
/// <inheritdoc cref="IMapping.LogMapping" />
|
||||
public bool LogMapping => !(Provider is DynamicResponseProvider || Provider is DynamicAsyncResponseProvider);
|
||||
|
||||
/// <inheritdoc cref="IMapping.Webhooks" />
|
||||
public IWebhook[] Webhooks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
||||
/// </summary>
|
||||
@@ -68,6 +72,7 @@ namespace WireMock
|
||||
/// <param name="executionConditionState">State in which the current mapping can occur. [Optional]</param>
|
||||
/// <param name="nextState">The next state which will occur after the current mapping execution. [Optional]</param>
|
||||
/// <param name="stateTimes">Only when the current state is executed this number, the next state which will occur. [Optional]</param>
|
||||
/// <param name="webhooks">The Webhooks. [Optional]</param>
|
||||
public Mapping(
|
||||
Guid guid,
|
||||
[CanBeNull] string title,
|
||||
@@ -79,7 +84,8 @@ namespace WireMock
|
||||
[CanBeNull] string scenario,
|
||||
[CanBeNull] string executionConditionState,
|
||||
[CanBeNull] string nextState,
|
||||
[CanBeNull] int? stateTimes)
|
||||
[CanBeNull] int? stateTimes,
|
||||
[CanBeNull] IWebhook[] webhooks)
|
||||
{
|
||||
Guid = guid;
|
||||
Title = title;
|
||||
@@ -92,10 +98,11 @@ namespace WireMock
|
||||
ExecutionConditionState = executionConditionState;
|
||||
NextState = nextState;
|
||||
StateTimes = stateTimes;
|
||||
Webhooks = webhooks;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMapping.ProvideResponseAsync" />
|
||||
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage)
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage)
|
||||
{
|
||||
return await Provider.ProvideResponseAsync(requestMessage, Settings);
|
||||
}
|
||||
|
||||
@@ -1,164 +1,195 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using WireMock.Types;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The request body matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The body function
|
||||
/// </summary>
|
||||
public Func<string, bool> Func { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for byte[]
|
||||
/// </summary>
|
||||
public Func<byte[], bool> DataFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for json
|
||||
/// </summary>
|
||||
public Func<object, bool> JsonFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IMatcher[] Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] string body) : this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] object body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
Func = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
DataFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
JsonFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] params IMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(matchers, nameof(matchers));
|
||||
Matchers = matchers;
|
||||
}
|
||||
|
||||
/// <see cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
||||
{
|
||||
// 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 == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null && Matchers.Any())
|
||||
{
|
||||
return Matchers.Max(matcher => CalculateMatchScore(requestMessage, matcher));
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
{
|
||||
return MatchScores.ToScore(Func(requestMessage?.BodyData?.BodyAsString));
|
||||
}
|
||||
|
||||
if (JsonFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(JsonFunc(requestMessage?.BodyData?.BodyAsJson));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(DataFunc(requestMessage?.BodyData?.BodyAsBytes));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The request body matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The body function
|
||||
/// </summary>
|
||||
public Func<string, bool> Func { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for byte[]
|
||||
/// </summary>
|
||||
public Func<byte[], bool> DataFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for json
|
||||
/// </summary>
|
||||
public Func<object, bool> JsonFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body data function for BodyData
|
||||
/// </summary>
|
||||
public Func<IBodyData, bool> BodyDataFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IMatcher[] Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] string body) : this(new[] { new WildcardMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] byte[] body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
public RequestMessageBodyMatcher(MatchBehaviour matchBehaviour, [NotNull] object body) : this(new[] { new ExactObjectMatcher(matchBehaviour, body) }.Cast<IMatcher>().ToArray())
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<string, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
Func = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<byte[], bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
DataFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<object, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
JsonFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] Func<IBodyData, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
BodyDataFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageBodyMatcher([NotNull] params IMatcher[] matchers)
|
||||
{
|
||||
Check.NotNull(matchers, nameof(matchers));
|
||||
Matchers = matchers;
|
||||
}
|
||||
|
||||
/// <see cref="IRequestMatcher.GetMatchingScore"/>
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, RequestMatchResult requestMatchResult)
|
||||
{
|
||||
double score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
||||
{
|
||||
if (matcher is ExactObjectMatcher exactObjectMatcher)
|
||||
{
|
||||
// If the body is a byte array, try to match.
|
||||
var detectedBodyType = requestMessage?.BodyData?.DetectedBodyType;
|
||||
if (detectedBodyType == BodyType.Bytes || detectedBodyType == BodyType.String)
|
||||
{
|
||||
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 == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers != null && Matchers.Any())
|
||||
{
|
||||
return Matchers.Max(matcher => CalculateMatchScore(requestMessage, matcher));
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
{
|
||||
return MatchScores.ToScore(Func(requestMessage?.BodyData?.BodyAsString));
|
||||
}
|
||||
|
||||
if (JsonFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(JsonFunc(requestMessage?.BodyData?.BodyAsJson));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(DataFunc(requestMessage?.BodyData?.BodyAsBytes));
|
||||
}
|
||||
|
||||
if (BodyDataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(BodyDataFunc(requestMessage?.BodyData));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/WireMock.Net/Models/Webhook.cs
Normal file
11
src/WireMock.Net/Models/Webhook.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace WireMock.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Webhook
|
||||
/// </summary>
|
||||
public class Webhook : IWebhook
|
||||
{
|
||||
/// <inheritdoc cref="IWebhook.Request"/>
|
||||
public IWebhookRequest Request { get; set; }
|
||||
}
|
||||
}
|
||||
30
src/WireMock.Net/Models/WebhookRequest.cs
Normal file
30
src/WireMock.Net/Models/WebhookRequest.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// WebhookRequest
|
||||
/// </summary>
|
||||
public class WebhookRequest : IWebhookRequest
|
||||
{
|
||||
/// <inheritdoc cref="IWebhookRequest.Url"/>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.Method"/>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.Headers"/>
|
||||
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.BodyData"/>
|
||||
public IBodyData BodyData { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.UseTransformer"/>
|
||||
public bool? UseTransformer { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWebhookRequest.TransformerType"/>
|
||||
public TransformerType TransformerType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ namespace WireMock.Owin
|
||||
{
|
||||
if (urlDetail.IsHttps)
|
||||
{
|
||||
kestrelOptions.Listen(System.Net.IPAddress.Any, urlDetail.Port, listenOptions =>
|
||||
kestrelOptions.ListenAnyIP(urlDetail.Port, listenOptions =>
|
||||
{
|
||||
if (wireMockMiddlewareOptions.CustomCertificateDefined)
|
||||
{
|
||||
@@ -45,7 +45,7 @@ namespace WireMock.Owin
|
||||
}
|
||||
else
|
||||
{
|
||||
kestrelOptions.Listen(System.Net.IPAddress.Any, urlDetail.Port);
|
||||
kestrelOptions.ListenAnyIP(urlDetail.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ namespace WireMock.Owin
|
||||
services.AddSingleton<IMappingMatcher, MappingMatcher>();
|
||||
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
|
||||
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
|
||||
|
||||
_wireMockMiddlewareOptions.AdditionalServiceRegistration?.Invoke(services);
|
||||
})
|
||||
.Configure(appBuilder =>
|
||||
{
|
||||
@@ -106,7 +108,7 @@ namespace WireMock.Owin
|
||||
|
||||
foreach (string address in addresses)
|
||||
{
|
||||
Urls.Add(address.Replace("0.0.0.0", "localhost"));
|
||||
Urls.Add(address.Replace("0.0.0.0", "localhost").Replace("[::]", "localhost"));
|
||||
|
||||
PortUtils.TryExtract(address, out bool isHttps, out string protocol, out string host, out int port);
|
||||
Ports.Add(port);
|
||||
|
||||
@@ -8,6 +8,7 @@ using WireMock.Util;
|
||||
using Owin;
|
||||
#else
|
||||
using IAppBuilder = Microsoft.AspNetCore.Builder.IApplicationBuilder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin
|
||||
@@ -36,6 +37,10 @@ namespace WireMock.Owin
|
||||
|
||||
Action<IAppBuilder> PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
#endif
|
||||
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
}
|
||||
|
||||
BodyData body = null;
|
||||
IBodyData body = null;
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
|
||||
{
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
|
||||
@@ -154,7 +154,13 @@ namespace WireMock.Owin.Mappers
|
||||
private static void SetResponseHeaders(ResponseMessage responseMessage, IResponse response)
|
||||
{
|
||||
// Force setting the Date header (#577)
|
||||
AppendResponseHeader(response, HttpKnownHeaderNames.Date, new[] { string.Format(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, DateTime.Now) });
|
||||
AppendResponseHeader(
|
||||
response,
|
||||
HttpKnownHeaderNames.Date,
|
||||
new[]
|
||||
{
|
||||
DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture)
|
||||
});
|
||||
|
||||
// Set other headers
|
||||
foreach (var item in responseMessage.Headers)
|
||||
|
||||
@@ -9,6 +9,7 @@ using WireMock.Serialization;
|
||||
using WireMock.Types;
|
||||
using WireMock.Validation;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
#if !USE_ASPNETCORE
|
||||
using Microsoft.Owin;
|
||||
using IContext = Microsoft.Owin.IOwinContext;
|
||||
@@ -128,15 +129,16 @@ namespace WireMock.Owin
|
||||
await Task.Delay(_options.RequestProcessingDelay.Value);
|
||||
}
|
||||
|
||||
response = await targetMapping.ProvideResponseAsync(request);
|
||||
var (theResponse, theOptionalNewMapping) = await targetMapping.ProvideResponseAsync(request);
|
||||
response = theResponse;
|
||||
|
||||
var responseBuilder = targetMapping.Provider as Response;
|
||||
|
||||
if (!targetMapping.IsAdminInterface)
|
||||
if (!targetMapping.IsAdminInterface && theOptionalNewMapping != null)
|
||||
{
|
||||
if (responseBuilder?.ProxyAndRecordSettings?.SaveMapping == true || targetMapping?.Settings?.ProxyAndRecordSettings?.SaveMapping == true)
|
||||
{
|
||||
_options.Mappings.TryAdd(targetMapping.Guid, targetMapping);
|
||||
_options.Mappings.TryAdd(theOptionalNewMapping.Guid, theOptionalNewMapping);
|
||||
}
|
||||
|
||||
if (responseBuilder?.ProxyAndRecordSettings?.SaveMappingToFile == true || targetMapping?.Settings?.ProxyAndRecordSettings?.SaveMappingToFile == true)
|
||||
@@ -145,7 +147,7 @@ namespace WireMock.Owin
|
||||
var mappingConverter = new MappingConverter(matcherMapper);
|
||||
var mappingToFileSaver = new MappingToFileSaver(targetMapping.Settings, mappingConverter);
|
||||
|
||||
mappingToFileSaver.SaveMappingToFile(targetMapping);
|
||||
mappingToFileSaver.SaveMappingToFile(theOptionalNewMapping);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +155,11 @@ namespace WireMock.Owin
|
||||
{
|
||||
UpdateScenarioState(targetMapping);
|
||||
}
|
||||
|
||||
if (!targetMapping.IsAdminInterface && targetMapping.Webhooks?.Length > 0)
|
||||
{
|
||||
await SendToWebhooksAsync(targetMapping, request, response).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -184,6 +191,24 @@ namespace WireMock.Owin
|
||||
await CompletedTask;
|
||||
}
|
||||
|
||||
private async Task SendToWebhooksAsync(IMapping mapping, RequestMessage request, ResponseMessage response)
|
||||
{
|
||||
for (int index = 0; index < mapping.Webhooks.Length; index++)
|
||||
{
|
||||
var httpClientForWebhook = HttpClientBuilder.Build(mapping.Settings.WebhookSettings ?? new WebhookSettings());
|
||||
var webhookSender = new WebhookSender(mapping.Settings);
|
||||
|
||||
try
|
||||
{
|
||||
await webhookSender.SendAsync(httpClientForWebhook, mapping.Webhooks[index].Request, request, response).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_options.Logger.Error($"Sending message to Webhook [{index}] from Mapping '{mapping.Guid}' failed. Exception: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateScenarioState(IMapping mapping)
|
||||
{
|
||||
var scenario = _options.Scenarios[mapping.Scenario];
|
||||
|
||||
@@ -8,6 +8,7 @@ using WireMock.Util;
|
||||
using Owin;
|
||||
#else
|
||||
using IAppBuilder = Microsoft.AspNetCore.Builder.IApplicationBuilder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Owin
|
||||
@@ -36,6 +37,10 @@ namespace WireMock.Owin
|
||||
|
||||
public Action<IAppBuilder> PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
public Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
#endif
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.FileSystemHandler"/>
|
||||
public IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
|
||||
@@ -1,112 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using HandlebarsDotNet.Helpers.Validation;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Proxy
|
||||
{
|
||||
internal class ProxyHelper
|
||||
{
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
|
||||
public ProxyHelper([NotNull] IWireMockServerSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public async Task<(ResponseMessage ResponseMessage, IMapping Mapping)> SendAsync(
|
||||
[NotNull] IProxyAndRecordSettings proxyAndRecordSettings,
|
||||
[NotNull] HttpClient client,
|
||||
[NotNull] RequestMessage requestMessage,
|
||||
[NotNull] string url)
|
||||
{
|
||||
Check.NotNull(client, nameof(client));
|
||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||
Check.NotNull(url, nameof(url));
|
||||
|
||||
var originalUri = new Uri(requestMessage.Url);
|
||||
var requiredUri = new Uri(url);
|
||||
|
||||
// Create HttpRequestMessage
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);
|
||||
|
||||
// Call the URL
|
||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
||||
|
||||
// Create ResponseMessage
|
||||
bool deserializeJson = !_settings.DisableJsonBodyParsing.GetValueOrDefault(false);
|
||||
bool decompressGzipAndDeflate = !_settings.DisableRequestBodyDecompressing.GetValueOrDefault(false);
|
||||
|
||||
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate);
|
||||
|
||||
IMapping mapping = null;
|
||||
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
||||
{
|
||||
mapping = ToMapping(proxyAndRecordSettings, requestMessage, responseMessage);
|
||||
}
|
||||
|
||||
return (responseMessage, mapping);
|
||||
}
|
||||
|
||||
private IMapping ToMapping(IProxyAndRecordSettings proxyAndRecordSettings, RequestMessage requestMessage, ResponseMessage responseMessage)
|
||||
{
|
||||
string[] excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
|
||||
string[] excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
||||
|
||||
var request = Request.Create();
|
||||
request.WithPath(requestMessage.Path);
|
||||
request.UsingMethod(requestMessage.Method);
|
||||
|
||||
requestMessage.Query.Loop((key, value) => request.WithParam(key, false, value.ToArray()));
|
||||
requestMessage.Cookies.Loop((key, value) =>
|
||||
{
|
||||
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
request.WithCookie(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
var allExcludedHeaders = new List<string>(excludedHeaders) { "Cookie" };
|
||||
requestMessage.Headers.Loop((key, value) =>
|
||||
{
|
||||
if (!allExcludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
request.WithHeader(key, value.ToArray());
|
||||
}
|
||||
});
|
||||
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson, true, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, requestMessage.BodyData.BodyAsString));
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
}
|
||||
|
||||
var response = Response.Create(responseMessage);
|
||||
|
||||
return new Mapping(Guid.NewGuid(), string.Empty, null, _settings, request, response, 0, null, null, null, null);
|
||||
}
|
||||
}
|
||||
namespace WireMock.Proxy
|
||||
{
|
||||
internal class ProxyHelper
|
||||
{
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
|
||||
public ProxyHelper([NotNull] IWireMockServerSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> SendAsync(
|
||||
[NotNull] IProxyAndRecordSettings proxyAndRecordSettings,
|
||||
[NotNull] HttpClient client,
|
||||
[NotNull] RequestMessage requestMessage,
|
||||
[NotNull] string url)
|
||||
{
|
||||
Check.NotNull(client, nameof(client));
|
||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||
Check.NotNull(url, nameof(url));
|
||||
|
||||
var originalUri = new Uri(requestMessage.Url);
|
||||
var requiredUri = new Uri(url);
|
||||
|
||||
// Create HttpRequestMessage
|
||||
var httpRequestMessage = HttpRequestMessageHelper.Create(requestMessage, url);
|
||||
|
||||
// Call the URL
|
||||
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
|
||||
|
||||
// Create ResponseMessage
|
||||
bool deserializeJson = !_settings.DisableJsonBodyParsing.GetValueOrDefault(false);
|
||||
bool decompressGzipAndDeflate = !_settings.DisableRequestBodyDecompressing.GetValueOrDefault(false);
|
||||
|
||||
var responseMessage = await HttpResponseMessageHelper.CreateAsync(httpResponseMessage, requiredUri, originalUri, deserializeJson, decompressGzipAndDeflate);
|
||||
|
||||
IMapping mapping = null;
|
||||
if (HttpStatusRangeParser.IsMatch(proxyAndRecordSettings.SaveMappingForStatusCodePattern, responseMessage.StatusCode) &&
|
||||
(proxyAndRecordSettings.SaveMapping || proxyAndRecordSettings.SaveMappingToFile))
|
||||
{
|
||||
mapping = ToMapping(proxyAndRecordSettings, requestMessage, responseMessage);
|
||||
}
|
||||
|
||||
return (responseMessage, mapping);
|
||||
}
|
||||
|
||||
private IMapping ToMapping(IProxyAndRecordSettings proxyAndRecordSettings, RequestMessage requestMessage, ResponseMessage responseMessage)
|
||||
{
|
||||
string[] excludedHeaders = proxyAndRecordSettings.ExcludedHeaders ?? new string[] { };
|
||||
string[] excludedCookies = proxyAndRecordSettings.ExcludedCookies ?? new string[] { };
|
||||
|
||||
var request = Request.Create();
|
||||
request.WithPath(requestMessage.Path);
|
||||
request.UsingMethod(requestMessage.Method);
|
||||
|
||||
requestMessage.Query.Loop((key, value) => request.WithParam(key, false, value.ToArray()));
|
||||
requestMessage.Cookies.Loop((key, value) =>
|
||||
{
|
||||
if (!excludedCookies.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
request.WithCookie(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
var allExcludedHeaders = new List<string>(excludedHeaders) { "Cookie" };
|
||||
requestMessage.Headers.Loop((key, value) =>
|
||||
{
|
||||
if (!allExcludedHeaders.Contains(key, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
request.WithHeader(key, value.ToArray());
|
||||
}
|
||||
});
|
||||
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson, true, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, throwExceptionWhenMatcherFails, requestMessage.BodyData.BodyAsString));
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
request.WithBody(new ExactObjectMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsBytes, throwExceptionWhenMatcherFails));
|
||||
break;
|
||||
}
|
||||
|
||||
var response = Response.Create(responseMessage);
|
||||
|
||||
return new Mapping(Guid.NewGuid(), string.Empty, null, _settings, request, response, 0, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,8 @@
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
/// <summary>
|
||||
@@ -63,10 +64,17 @@ namespace WireMock.RequestBuilders
|
||||
IRequestBuilder WithBody([NotNull] Func<byte[], bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (object)
|
||||
/// WithBody: func (json object)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] Func<object, bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody: func (BodyData object)
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody([NotNull] Func<IBodyData, bool> func);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
@@ -71,5 +72,14 @@ namespace WireMock.RequestBuilders
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyRequestBuilder.WithBody(Func{IBodyData, bool})"/>
|
||||
public IRequestBuilder WithBody(Func<IBodyData, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace WireMock
|
||||
/// <param name="bodyData">The BodyData.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData bodyData = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||
public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] IBodyData bodyData = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||
{
|
||||
Check.NotNull(urlDetails, nameof(urlDetails));
|
||||
Check.NotNull(method, nameof(method));
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using JetBrains.Annotations;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace WireMock.ResponseBuilders
|
||||
{
|
||||
/// <summary>
|
||||
@@ -27,6 +28,15 @@ namespace WireMock.ResponseBuilders
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody([NotNull] Func<RequestMessage, string> bodyFactory, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a callback function.
|
||||
/// </summary>
|
||||
/// <param name="bodyFactory">The async delegate to build the body.</param>
|
||||
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
|
||||
/// <param name="encoding">The body encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBody([NotNull] Func<RequestMessage, Task<string>> bodyFactory, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBody : Create a ... response based on a bytearray.
|
||||
/// </summary>
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace WireMock.ResponseBuilders
|
||||
{
|
||||
Check.NotNull(bodyFactory, nameof(bodyFactory));
|
||||
|
||||
return WithCallbackInternal(false, req => new ResponseMessage
|
||||
return WithCallbackInternal(true, req => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
@@ -178,6 +178,22 @@ namespace WireMock.ResponseBuilders
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, Task{string}}, string, Encoding)"/>
|
||||
public IResponseBuilder WithBody(Func<RequestMessage, Task<string>> bodyFactory, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
{
|
||||
Check.NotNull(bodyFactory, nameof(bodyFactory));
|
||||
|
||||
return WithCallbackInternal(true, async req => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = await bodyFactory(req),
|
||||
Encoding = encoding ?? Encoding.UTF8
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(byte[], string, Encoding)"/>
|
||||
public IResponseBuilder WithBody(byte[] body, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
{
|
||||
@@ -319,7 +335,7 @@ namespace WireMock.ResponseBuilders
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IResponseProvider.ProvideResponseAsync(RequestMessage, IWireMockServerSettings)"/>
|
||||
public async Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
{
|
||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
@@ -345,18 +361,16 @@ namespace WireMock.ResponseBuilders
|
||||
|
||||
var proxyHelper = new ProxyHelper(settings);
|
||||
|
||||
var (proxyResponseMessage, _) = await proxyHelper.SendAsync(
|
||||
return await proxyHelper.SendAsync(
|
||||
ProxyAndRecordSettings,
|
||||
_httpClientForProxy,
|
||||
requestMessage,
|
||||
requestMessage.ProxyUrl
|
||||
);
|
||||
|
||||
return proxyResponseMessage;
|
||||
}
|
||||
|
||||
ResponseMessage responseMessage;
|
||||
if (Callback == null && CallbackAsync == null)
|
||||
if (!WithCallbackUsed)
|
||||
{
|
||||
responseMessage = ResponseMessage;
|
||||
}
|
||||
@@ -371,16 +385,16 @@ namespace WireMock.ResponseBuilders
|
||||
responseMessage = await CallbackAsync(requestMessage);
|
||||
}
|
||||
|
||||
if (!WithCallbackUsed)
|
||||
// Copy StatusCode from ResponseMessage (if defined)
|
||||
if (ResponseMessage.StatusCode != null)
|
||||
{
|
||||
// Copy StatusCode from ResponseMessage
|
||||
responseMessage.StatusCode = ResponseMessage.StatusCode;
|
||||
}
|
||||
|
||||
// Copy Headers from ResponseMessage (if defined)
|
||||
if (ResponseMessage.Headers != null)
|
||||
{
|
||||
responseMessage.Headers = ResponseMessage.Headers;
|
||||
}
|
||||
// Copy Headers from ResponseMessage (if defined)
|
||||
if (ResponseMessage.Headers?.Count > 0)
|
||||
{
|
||||
responseMessage.Headers = ResponseMessage.Headers;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +418,7 @@ namespace WireMock.ResponseBuilders
|
||||
throw new NotImplementedException($"TransformerType '{TransformerType}' is not supported.");
|
||||
}
|
||||
|
||||
return responseMessageTransformer.Transform(requestMessage, responseMessage, UseTransformerForBodyAsFile);
|
||||
return (responseMessageTransformer.Transform(requestMessage, responseMessage, UseTransformerForBodyAsFile), null);
|
||||
}
|
||||
|
||||
if (!UseTransformer && ResponseMessage.BodyData?.BodyAsFileIsCached == true)
|
||||
@@ -412,7 +426,7 @@ namespace WireMock.ResponseBuilders
|
||||
ResponseMessage.BodyData.BodyAsBytes = settings.FileSystemHandler.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile);
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
return (responseMessage, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,9 @@ namespace WireMock.ResponseProviders
|
||||
_responseMessageFunc = responseMessageFunc;
|
||||
}
|
||||
|
||||
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
{
|
||||
return _responseMessageFunc(requestMessage);
|
||||
return (await _responseMessageFunc(requestMessage), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,10 @@ namespace WireMock.ResponseProviders
|
||||
_responseMessageFunc = responseMessageFunc;
|
||||
}
|
||||
|
||||
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
public Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
{
|
||||
return Task.FromResult(_responseMessageFunc(requestMessage));
|
||||
(ResponseMessage responseMessage, IMapping mapping) result = (_responseMessageFunc(requestMessage), null);
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace WireMock.ResponseProviders
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request.</param>
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <returns>The <see cref="ResponseMessage"/>.</returns>
|
||||
Task<ResponseMessage> ProvideResponseAsync([NotNull] RequestMessage requestMessage, [NotNull] IWireMockServerSettings settings);
|
||||
/// <returns>The <see cref="ResponseMessage"/> including a new (optional) <see cref="IMapping"/>.</returns>
|
||||
Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync([NotNull] RequestMessage requestMessage, [NotNull] IWireMockServerSettings settings);
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,9 @@ namespace WireMock.ResponseProviders
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public Task<ResponseMessage> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
public async Task<(ResponseMessage Message, IMapping Mapping)> ProvideResponseAsync(RequestMessage requestMessage, IWireMockServerSettings settings)
|
||||
{
|
||||
return _responseMessageFunc(requestMessage, _settings);
|
||||
return (await _responseMessageFunc(requestMessage, _settings), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,15 @@ namespace WireMock.Serialization
|
||||
}
|
||||
};
|
||||
|
||||
if (mapping.Webhooks?.Length == 1)
|
||||
{
|
||||
mappingModel.Webhook = WebhookMapper.Map(mapping.Webhooks[0]);
|
||||
}
|
||||
else if (mapping.Webhooks?.Length > 1)
|
||||
{
|
||||
mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
|
||||
}
|
||||
|
||||
if (bodyMatcher?.Matchers != null)
|
||||
{
|
||||
mappingModel.Request.Body = new BodyModel();
|
||||
|
||||
103
src/WireMock.Net/Serialization/WebhookMapper.cs
Normal file
103
src/WireMock.Net/Serialization/WebhookMapper.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Http;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Serialization
|
||||
{
|
||||
internal static class WebhookMapper
|
||||
{
|
||||
public static IWebhook Map(WebhookModel model)
|
||||
{
|
||||
var webhook = new Webhook
|
||||
{
|
||||
Request = new WebhookRequest
|
||||
{
|
||||
Url = model.Request.Url,
|
||||
Method = model.Request.Method,
|
||||
Headers = model.Request.Headers?.ToDictionary(x => x.Key, x => new WireMockList<string>(x.Value)) ?? new Dictionary<string, WireMockList<string>>()
|
||||
}
|
||||
};
|
||||
|
||||
if (model.Request.UseTransformer == true)
|
||||
{
|
||||
webhook.Request.UseTransformer = true;
|
||||
if (!Enum.TryParse<TransformerType>(model.Request.TransformerType, out var transformerType))
|
||||
{
|
||||
transformerType = TransformerType.Handlebars;
|
||||
}
|
||||
webhook.Request.TransformerType = transformerType;
|
||||
}
|
||||
|
||||
IEnumerable<string> contentTypeHeader = null;
|
||||
if (webhook.Request.Headers.Any(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
contentTypeHeader = webhook.Request.Headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
if (model.Request.Body != null)
|
||||
{
|
||||
webhook.Request.BodyData = new BodyData
|
||||
{
|
||||
BodyAsString = model.Request.Body,
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = BodyParser.DetectBodyTypeFromContentType(contentTypeHeader?.FirstOrDefault())
|
||||
};
|
||||
}
|
||||
else if (model.Request.BodyAsJson != null)
|
||||
{
|
||||
webhook.Request.BodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = model.Request.BodyAsJson,
|
||||
DetectedBodyType = BodyType.Json,
|
||||
DetectedBodyTypeFromContentType = BodyParser.DetectBodyTypeFromContentType(contentTypeHeader?.FirstOrDefault())
|
||||
};
|
||||
}
|
||||
|
||||
return webhook;
|
||||
}
|
||||
|
||||
public static WebhookModel Map(IWebhook webhook)
|
||||
{
|
||||
if (webhook?.Request == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var model = new WebhookModel
|
||||
{
|
||||
Request = new WebhookRequestModel
|
||||
{
|
||||
Url = webhook.Request.Url,
|
||||
Method = webhook.Request.Method,
|
||||
Headers = webhook.Request.Headers?.ToDictionary(x => x.Key, x => x.Value.ToString()),
|
||||
UseTransformer = webhook.Request.UseTransformer,
|
||||
TransformerType = webhook.Request.UseTransformer == true ? webhook.Request.TransformerType.ToString() : null
|
||||
}
|
||||
};
|
||||
|
||||
if (webhook.Request.BodyData != null)
|
||||
{
|
||||
switch (webhook.Request.BodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.String:
|
||||
model.Request.Body = webhook.Request.BodyData.BodyAsString;
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
model.Request.BodyAsJson = webhook.Request.BodyData.BodyAsJson;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Server
|
||||
{
|
||||
@@ -97,5 +101,50 @@ namespace WireMock.Server
|
||||
/// <param name="times">The number of times this match should be matched before the state will be changed to the specified one. Default value is 1.</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WillSetStateTo(int state, int? times = 1);
|
||||
|
||||
/// <summary>
|
||||
/// Add (multiple) Webhook(s) to call after the response has been generated.
|
||||
/// </summary>
|
||||
/// <param name="webhooks">The Webhooks</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithWebhook(params IWebhook[] webhooks);
|
||||
|
||||
/// <summary>
|
||||
/// Add a Webhook to call after the response has been generated.
|
||||
/// </summary>
|
||||
/// <param name="url">The Webhook Url</param>
|
||||
/// <param name="method">The method to use. [optional]</param>
|
||||
/// <param name="headers">The Headers to send. [optional]</param>
|
||||
/// <param name="body">The body (as string) to send. [optional]</param>
|
||||
/// <param name="useTransformer">Use Transformer. [optional]</param>
|
||||
/// <param name="transformerType">The transformer type. [optional]</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithWebhook(
|
||||
[NotNull] string url,
|
||||
[CanBeNull] string method = "post",
|
||||
[CanBeNull] IDictionary<string, WireMockList<string>> headers = null,
|
||||
[CanBeNull] string body = null,
|
||||
bool useTransformer = true,
|
||||
TransformerType transformerType = TransformerType.Handlebars
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Add a Webhook to call after the response has been generated.
|
||||
/// </summary>
|
||||
/// <param name="url">The Webhook Url</param>
|
||||
/// <param name="method">The method to use. [optional]</param>
|
||||
/// <param name="headers">The Headers to send. [optional]</param>
|
||||
/// <param name="body">The body (as json) to send. [optional]</param>
|
||||
/// <param name="useTransformer">Use Transformer. [optional]</param>
|
||||
/// <param name="transformerType">The transformer type. [optional]</param>
|
||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||
IRespondWithAProvider WithWebhook(
|
||||
[NotNull] string url,
|
||||
[CanBeNull] string method = "post",
|
||||
[CanBeNull] IDictionary<string, WireMockList<string>> headers = null,
|
||||
[CanBeNull] object body = null,
|
||||
bool useTransformer = true,
|
||||
TransformerType transformerType = TransformerType.Handlebars
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,144 +1,230 @@
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// The respond with a provider.
|
||||
/// </summary>
|
||||
internal class RespondWithAProvider : IRespondWithAProvider
|
||||
{
|
||||
private int _priority;
|
||||
private string _title;
|
||||
private string _path;
|
||||
private string _executionConditionState;
|
||||
private string _nextState;
|
||||
private string _scenario;
|
||||
private int _timesInSameState = 1;
|
||||
private readonly RegistrationCallback _registrationCallback;
|
||||
private readonly IRequestMatcher _requestMatcher;
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
private readonly bool _saveToFile;
|
||||
|
||||
public Guid Guid { get; private set; } = Guid.NewGuid();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registrationCallback">The registration callback.</param>
|
||||
/// <param name="requestMatcher">The request matcher.</param>
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <param name="saveToFile">Optional boolean to indicate if this mapping should be saved as static mapping file.</param>
|
||||
public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher, IWireMockServerSettings settings, bool saveToFile = false)
|
||||
{
|
||||
_registrationCallback = registrationCallback;
|
||||
_requestMatcher = requestMatcher;
|
||||
_settings = settings;
|
||||
_saveToFile = saveToFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The respond with.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider.</param>
|
||||
public void RespondWith(IResponseProvider provider)
|
||||
{
|
||||
_registrationCallback(new Mapping(Guid, _title, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState), _saveToFile);
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>
|
||||
public IRespondWithAProvider WithGuid(string guid)
|
||||
{
|
||||
return WithGuid(Guid.Parse(guid));
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>
|
||||
public IRespondWithAProvider WithGuid(Guid guid)
|
||||
{
|
||||
Guid = guid;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithTitle"/>
|
||||
public IRespondWithAProvider WithTitle(string title)
|
||||
{
|
||||
_title = title;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithPath"/>
|
||||
public IRespondWithAProvider WithPath(string path)
|
||||
{
|
||||
_path = path;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.AtPriority"/>
|
||||
public IRespondWithAProvider AtPriority(int priority)
|
||||
{
|
||||
_priority = priority;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.InScenario(string)"/>
|
||||
public IRespondWithAProvider InScenario(string scenario)
|
||||
{
|
||||
_scenario = scenario;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.InScenario(int)"/>
|
||||
public IRespondWithAProvider InScenario(int scenario)
|
||||
{
|
||||
return InScenario(scenario.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(string)"/>
|
||||
public IRespondWithAProvider WhenStateIs(string state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
{
|
||||
throw new NotSupportedException("Unable to set state condition when no scenario is defined.");
|
||||
}
|
||||
|
||||
_executionConditionState = state;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(int)"/>
|
||||
public IRespondWithAProvider WhenStateIs(int state)
|
||||
{
|
||||
return WhenStateIs(state.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(string, int?)"/>
|
||||
public IRespondWithAProvider WillSetStateTo(string state, int? times = 1)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
{
|
||||
throw new NotSupportedException("Unable to set next state when no scenario is defined.");
|
||||
}
|
||||
|
||||
_nextState = state;
|
||||
_timesInSameState = times ?? 1;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(int, int?)"/>
|
||||
public IRespondWithAProvider WillSetStateTo(int state, int? times = 1)
|
||||
{
|
||||
return WillSetStateTo(state.ToString(), times);
|
||||
}
|
||||
}
|
||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Server
|
||||
{
|
||||
/// <summary>
|
||||
/// The respond with a provider.
|
||||
/// </summary>
|
||||
internal class RespondWithAProvider : IRespondWithAProvider
|
||||
{
|
||||
private int _priority;
|
||||
private string _title;
|
||||
private string _path;
|
||||
private string _executionConditionState;
|
||||
private string _nextState;
|
||||
private string _scenario;
|
||||
private int _timesInSameState = 1;
|
||||
private readonly RegistrationCallback _registrationCallback;
|
||||
private readonly IRequestMatcher _requestMatcher;
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
private readonly bool _saveToFile;
|
||||
|
||||
public Guid Guid { get; private set; } = Guid.NewGuid();
|
||||
|
||||
public IWebhook[] Webhooks { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.
|
||||
/// </summary>
|
||||
/// <param name="registrationCallback">The registration callback.</param>
|
||||
/// <param name="requestMatcher">The request matcher.</param>
|
||||
/// <param name="settings">The WireMockServerSettings.</param>
|
||||
/// <param name="saveToFile">Optional boolean to indicate if this mapping should be saved as static mapping file.</param>
|
||||
public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher, IWireMockServerSettings settings, bool saveToFile = false)
|
||||
{
|
||||
_registrationCallback = registrationCallback;
|
||||
_requestMatcher = requestMatcher;
|
||||
_settings = settings;
|
||||
_saveToFile = saveToFile;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The respond with.
|
||||
/// </summary>
|
||||
/// <param name="provider">The provider.</param>
|
||||
public void RespondWith(IResponseProvider provider)
|
||||
{
|
||||
_registrationCallback(new Mapping(Guid, _title, _path, _settings, _requestMatcher, provider, _priority, _scenario, _executionConditionState, _nextState, _timesInSameState, Webhooks), _saveToFile);
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithGuid(string)"/>
|
||||
public IRespondWithAProvider WithGuid(string guid)
|
||||
{
|
||||
return WithGuid(Guid.Parse(guid));
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithGuid(Guid)"/>
|
||||
public IRespondWithAProvider WithGuid(Guid guid)
|
||||
{
|
||||
Guid = guid;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithTitle"/>
|
||||
public IRespondWithAProvider WithTitle(string title)
|
||||
{
|
||||
_title = title;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithPath"/>
|
||||
public IRespondWithAProvider WithPath(string path)
|
||||
{
|
||||
_path = path;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.AtPriority"/>
|
||||
public IRespondWithAProvider AtPriority(int priority)
|
||||
{
|
||||
_priority = priority;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.InScenario(string)"/>
|
||||
public IRespondWithAProvider InScenario(string scenario)
|
||||
{
|
||||
_scenario = scenario;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.InScenario(int)"/>
|
||||
public IRespondWithAProvider InScenario(int scenario)
|
||||
{
|
||||
return InScenario(scenario.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(string)"/>
|
||||
public IRespondWithAProvider WhenStateIs(string state)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
{
|
||||
throw new NotSupportedException("Unable to set state condition when no scenario is defined.");
|
||||
}
|
||||
|
||||
_executionConditionState = state;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WhenStateIs(int)"/>
|
||||
public IRespondWithAProvider WhenStateIs(int state)
|
||||
{
|
||||
return WhenStateIs(state.ToString());
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(string, int?)"/>
|
||||
public IRespondWithAProvider WillSetStateTo(string state, int? times = 1)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_scenario))
|
||||
{
|
||||
throw new NotSupportedException("Unable to set next state when no scenario is defined.");
|
||||
}
|
||||
|
||||
_nextState = state;
|
||||
_timesInSameState = times ?? 1;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WillSetStateTo(int, int?)"/>
|
||||
public IRespondWithAProvider WillSetStateTo(int state, int? times = 1)
|
||||
{
|
||||
return WillSetStateTo(state.ToString(), times);
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithWebhook(IWebhook[])"/>
|
||||
public IRespondWithAProvider WithWebhook(params IWebhook[] webhooks)
|
||||
{
|
||||
Check.HasNoNulls(webhooks, nameof(webhooks));
|
||||
|
||||
Webhooks = webhooks;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithWebhook(string, string, IDictionary{string, WireMockList{string}}, string, bool, TransformerType)"/>
|
||||
public IRespondWithAProvider WithWebhook(
|
||||
[NotNull] string url,
|
||||
[CanBeNull] string method = "post",
|
||||
[CanBeNull] IDictionary<string, WireMockList<string>> headers = null,
|
||||
[CanBeNull] string body = null,
|
||||
bool useTransformer = true,
|
||||
TransformerType transformerType = TransformerType.Handlebars)
|
||||
{
|
||||
Webhooks = new[] { InitWebhook(url, method, headers, useTransformer, transformerType) };
|
||||
|
||||
if (body != null)
|
||||
{
|
||||
Webhooks[0].Request.BodyData = new BodyData
|
||||
{
|
||||
BodyAsString = body,
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = BodyType.String
|
||||
};
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <see cref="IRespondWithAProvider.WithWebhook(string, string, IDictionary{string, WireMockList{string}}, object, bool, TransformerType)"/>
|
||||
public IRespondWithAProvider WithWebhook(
|
||||
[NotNull] string url,
|
||||
[CanBeNull] string method = "post",
|
||||
[CanBeNull] IDictionary<string, WireMockList<string>> headers = null,
|
||||
[CanBeNull] object body = null,
|
||||
bool useTransformer = true,
|
||||
TransformerType transformerType = TransformerType.Handlebars)
|
||||
{
|
||||
Webhooks = new[] { InitWebhook(url, method, headers, useTransformer, transformerType) };
|
||||
|
||||
if (body != null)
|
||||
{
|
||||
Webhooks[0].Request.BodyData = new BodyData
|
||||
{
|
||||
BodyAsJson = body,
|
||||
DetectedBodyType = BodyType.Json,
|
||||
DetectedBodyTypeFromContentType = BodyType.Json
|
||||
};
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private IWebhook InitWebhook(
|
||||
string url,
|
||||
string method,
|
||||
IDictionary<string, WireMockList<string>> headers,
|
||||
bool useTransformer,
|
||||
TransformerType transformerType)
|
||||
{
|
||||
return new Webhook
|
||||
{
|
||||
Request = new WebhookRequest
|
||||
{
|
||||
Url = url,
|
||||
Method = method ?? "post",
|
||||
Headers = headers,
|
||||
UseTransformer = useTransformer,
|
||||
TransformerType = transformerType
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -470,6 +470,16 @@ namespace WireMock.Server
|
||||
respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo);
|
||||
}
|
||||
|
||||
if (mappingModel.Webhook != null)
|
||||
{
|
||||
respondProvider = respondProvider.WithWebhook(WebhookMapper.Map(mappingModel.Webhook));
|
||||
}
|
||||
else if (mappingModel.Webhooks?.Length > 1)
|
||||
{
|
||||
var webhooks = mappingModel.Webhooks.Select(WebhookMapper.Map).ToArray();
|
||||
respondProvider = respondProvider.WithWebhook(webhooks);
|
||||
}
|
||||
|
||||
respondProvider.RespondWith(responseBuilder);
|
||||
|
||||
return respondProvider.Guid;
|
||||
|
||||
@@ -242,6 +242,7 @@ namespace WireMock.Server
|
||||
_mappingToFileSaver = new MappingToFileSaver(_settings, _mappingConverter);
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
_options.AdditionalServiceRegistration = _settings.AdditionalServiceRegistration;
|
||||
_httpServer = new AspNetCoreSelfHost(_options, urlOptions);
|
||||
#else
|
||||
_httpServer = new OwinSelfHost(_options, urlOptions);
|
||||
|
||||
17
src/WireMock.Net/Settings/HttpClientSettings.cs
Normal file
17
src/WireMock.Net/Settings/HttpClientSettings.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// HttpClientSettings
|
||||
/// </summary>
|
||||
public class HttpClientSettings : IHttpClientSettings
|
||||
{
|
||||
/// <inheritdoc cref="IHttpClientSettings.ClientX509Certificate2ThumbprintOrSubjectName"/>
|
||||
public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IHttpClientSettings.WebProxySettings"/>
|
||||
public IWebProxySettings WebProxySettings { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IHttpClientSettings.AllowAutoRedirect"/>
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
}
|
||||
24
src/WireMock.Net/Settings/IHttpClientSettings.cs
Normal file
24
src/WireMock.Net/Settings/IHttpClientSettings.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// IHttpClientSettings
|
||||
/// </summary>
|
||||
public interface IHttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
IWebProxySettings WebProxySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace WireMock.Settings
|
||||
/// <summary>
|
||||
/// IProxyAndRecordSettings
|
||||
/// </summary>
|
||||
public interface IProxyAndRecordSettings
|
||||
public interface IProxyAndRecordSettings : IHttpClientSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The URL to proxy.
|
||||
@@ -29,12 +29,6 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
bool SaveMappingToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines a list from headers which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
@@ -44,15 +38,5 @@ namespace WireMock.Settings
|
||||
/// Defines a list of cookies which will be excluded from the saved mappings.
|
||||
/// </summary>
|
||||
string[] ExcludedCookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the WebProxySettings.
|
||||
/// </summary>
|
||||
IWebProxySettings WebProxySettings { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Proxy requests should follow redirection (30x).
|
||||
/// </summary>
|
||||
bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
}
|
||||
9
src/WireMock.Net/Settings/IWebhookSettings.cs
Normal file
9
src/WireMock.Net/Settings/IWebhookSettings.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// IWebhookSettings
|
||||
/// </summary>
|
||||
public interface IWebhookSettings : IHttpClientSettings
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ using JetBrains.Annotations;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
#if USE_ASPNETCORE
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
@@ -109,6 +112,14 @@ namespace WireMock.Settings
|
||||
[PublicAPI]
|
||||
Action<object> PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <summary>
|
||||
/// Action which is called with IServiceCollection when ASP.NET Core DI is being configured. [Optional]
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// The IWireMockLogger which logs Debug, Info, Warning or Error
|
||||
/// </summary>
|
||||
@@ -186,5 +197,11 @@ namespace WireMock.Settings
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool CustomCertificateDefined { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines the global IWebhookSettingsto use
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
IWebhookSettings WebhookSettings { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace WireMock.Settings
|
||||
/// <summary>
|
||||
/// ProxyAndRecordSettings
|
||||
/// </summary>
|
||||
public class ProxyAndRecordSettings : IProxyAndRecordSettings
|
||||
public class ProxyAndRecordSettings : HttpClientSettings, IProxyAndRecordSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// The URL to proxy.
|
||||
@@ -32,13 +32,6 @@ namespace WireMock.Settings
|
||||
[PublicAPI]
|
||||
public string SaveMappingForStatusCodePattern { get; set; } = "*";
|
||||
|
||||
/// <summary>
|
||||
/// The clientCertificate thumbprint or subject name fragment to use.
|
||||
/// Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public string ClientX509Certificate2ThumbprintOrSubjectName { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.ExcludedHeaders"/>
|
||||
[PublicAPI]
|
||||
public string[] ExcludedHeaders { get; set; }
|
||||
@@ -46,13 +39,5 @@ namespace WireMock.Settings
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.ExcludedCookies"/>
|
||||
[PublicAPI]
|
||||
public string[] ExcludedCookies { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.WebProxySettings"/>
|
||||
[PublicAPI]
|
||||
public IWebProxySettings WebProxySettings { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IProxyAndRecordSettings.AllowAutoRedirect"/>
|
||||
[PublicAPI]
|
||||
public bool? AllowAutoRedirect { get; set; }
|
||||
}
|
||||
}
|
||||
9
src/WireMock.Net/Settings/WebhookSettings.cs
Normal file
9
src/WireMock.Net/Settings/WebhookSettings.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
/// <summary>
|
||||
/// WebhookSettings
|
||||
/// </summary>
|
||||
public class WebhookSettings : HttpClientSettings, IWebhookSettings
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
#if USE_ASPNETCORE
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
#endif
|
||||
|
||||
namespace WireMock.Settings
|
||||
{
|
||||
@@ -79,6 +82,13 @@ namespace WireMock.Settings
|
||||
[JsonIgnore]
|
||||
public Action<object> PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
#if USE_ASPNETCORE
|
||||
/// <inheritdoc cref="IWireMockServerSettings.AdditionalServiceRegistration"/>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
public Action<IServiceCollection> AdditionalServiceRegistration { get; set; }
|
||||
#endif
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.Logger"/>
|
||||
[PublicAPI]
|
||||
[JsonIgnore]
|
||||
@@ -129,5 +139,9 @@ namespace WireMock.Settings
|
||||
/// <inheritdoc cref="IWireMockServerSettings.CustomCertificateDefined"/>
|
||||
[PublicAPI]
|
||||
public bool CustomCertificateDefined => CertificateSettings?.IsDefined == true;
|
||||
|
||||
/// <inheritdoc cref="IWireMockServerSettings.WebhookSettings"/>
|
||||
[PublicAPI]
|
||||
public IWebhookSettings WebhookSettings { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
namespace WireMock.Transformers
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
interface ITransformer
|
||||
{
|
||||
ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile);
|
||||
|
||||
(IBodyData BodyData, IDictionary<string, WireMockList<string>> Headers) Transform(RequestMessage originalRequestMessage, ResponseMessage originalResponseMessage, IBodyData bodyData, IDictionary<string, WireMockList<string>> headers);
|
||||
}
|
||||
}
|
||||
@@ -1,227 +1,265 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers.Handlebars
|
||||
{
|
||||
internal class Transformer : ITransformer
|
||||
{
|
||||
private readonly ITransformerContextFactory _factory;
|
||||
|
||||
public Transformer([NotNull] ITransformerContextFactory factory)
|
||||
{
|
||||
Check.NotNull(factory, nameof(factory));
|
||||
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var handlebarsContext = _factory.Create();
|
||||
|
||||
var responseMessage = new ResponseMessage();
|
||||
|
||||
var model = new { request = requestMessage };
|
||||
|
||||
switch (original.BodyData?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
TransformBodyAsJson(handlebarsContext, model, original, responseMessage);
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
TransformBodyAsFile(handlebarsContext, model, original, responseMessage, useTransformerForBodyAsFile);
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
|
||||
TransformBodyAsString(handlebarsContext, model, original, responseMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
responseMessage.FaultType = original.FaultType;
|
||||
responseMessage.FaultPercentage = original.FaultPercentage;
|
||||
|
||||
// Headers
|
||||
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
||||
foreach (var header in original.Headers)
|
||||
{
|
||||
var headerKey = handlebarsContext.ParseAndRender(header.Key, model);
|
||||
var templateHeaderValues = header.Value
|
||||
.Select(text => handlebarsContext.ParseAndRender(text, model))
|
||||
.ToArray();
|
||||
|
||||
newHeaders.Add(headerKey, new WireMockList<string>(templateHeaderValues));
|
||||
}
|
||||
|
||||
responseMessage.Headers = newHeaders;
|
||||
|
||||
switch (original.StatusCode)
|
||||
{
|
||||
case int statusCodeAsInteger:
|
||||
responseMessage.StatusCode = statusCodeAsInteger;
|
||||
break;
|
||||
|
||||
case string statusCodeAsString:
|
||||
responseMessage.StatusCode = handlebarsContext.ParseAndRender(statusCodeAsString, model);
|
||||
break;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private static void TransformBodyAsJson(ITransformerContext handlebarsContext, object model, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
JToken jToken;
|
||||
switch (original.BodyData.BodyAsJson)
|
||||
{
|
||||
case JObject bodyAsJObject:
|
||||
jToken = bodyAsJObject.DeepClone();
|
||||
WalkNode(handlebarsContext, jToken, model);
|
||||
break;
|
||||
|
||||
case Array bodyAsArray:
|
||||
jToken = JArray.FromObject(bodyAsArray);
|
||||
WalkNode(handlebarsContext, jToken, model);
|
||||
break;
|
||||
|
||||
case string bodyAsString:
|
||||
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, model);
|
||||
break;
|
||||
|
||||
default:
|
||||
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
|
||||
WalkNode(handlebarsContext, jToken, model);
|
||||
break;
|
||||
}
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = original.BodyData.Encoding,
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsJson = jToken
|
||||
};
|
||||
}
|
||||
|
||||
private static JToken ReplaceSingleNode(ITransformerContext handlebarsContext, string stringValue, object model)
|
||||
{
|
||||
string transformedString = handlebarsContext.ParseAndRender(stringValue, model) as string;
|
||||
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
const string property = "_";
|
||||
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
|
||||
JToken node = dummy[property];
|
||||
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
|
||||
return dummy[property];
|
||||
}
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
private static void WalkNode(ITransformerContext handlebarsContext, JToken node, object model)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child.Value, model);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child, model);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.String)
|
||||
{
|
||||
// In case of string, try to transform the value.
|
||||
string stringValue = node.Value<string>();
|
||||
if (string.IsNullOrEmpty(stringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string transformedString = handlebarsContext.ParseAndRender(stringValue, model);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReplaceNodeValue(JToken node, string stringValue)
|
||||
{
|
||||
if (bool.TryParse(stringValue, out bool valueAsBoolean))
|
||||
{
|
||||
node.Replace(valueAsBoolean);
|
||||
return;
|
||||
}
|
||||
|
||||
JToken value;
|
||||
try
|
||||
{
|
||||
// Try to convert this string into a JsonObject
|
||||
value = JToken.Parse(stringValue);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and just keep string value and convert to JToken
|
||||
value = stringValue;
|
||||
}
|
||||
|
||||
node.Replace(value);
|
||||
}
|
||||
|
||||
private static void TransformBodyAsString(ITransformerContext handlebarsContext, object model, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = original.BodyData.Encoding,
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = handlebarsContext.ParseAndRender(original.BodyData.BodyAsString, model)
|
||||
};
|
||||
}
|
||||
|
||||
private void TransformBodyAsFile(ITransformerContext handlebarsContext, object model, ResponseMessage original, ResponseMessage responseMessage, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
string transformedBodyAsFilename = handlebarsContext.ParseAndRender(original.BodyData.BodyAsFile, model);
|
||||
|
||||
if (!useTransformerForBodyAsFile)
|
||||
{
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
|
||||
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = handlebarsContext.ParseAndRender(text, model),
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Transformers.Handlebars
|
||||
{
|
||||
internal class Transformer : ITransformer
|
||||
{
|
||||
private readonly ITransformerContextFactory _factory;
|
||||
|
||||
public Transformer([NotNull] ITransformerContextFactory factory)
|
||||
{
|
||||
_factory = factory ?? throw new ArgumentNullException(nameof(factory));
|
||||
}
|
||||
|
||||
public (IBodyData BodyData, IDictionary<string, WireMockList<string>> Headers) Transform(RequestMessage originalRequestMessage, ResponseMessage originalResponseMessage, IBodyData bodyData, IDictionary<string, WireMockList<string>> headers)
|
||||
{
|
||||
var transformerContext = _factory.Create();
|
||||
|
||||
var model = new
|
||||
{
|
||||
request = originalRequestMessage,
|
||||
response = originalResponseMessage
|
||||
};
|
||||
|
||||
IBodyData newBodyData = null;
|
||||
if (bodyData?.DetectedBodyType != null)
|
||||
{
|
||||
newBodyData = TransformBodyData(transformerContext, model, bodyData, false);
|
||||
}
|
||||
|
||||
return (newBodyData, TransformHeaders(transformerContext, model, headers));
|
||||
}
|
||||
|
||||
public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
var transformerContext = _factory.Create();
|
||||
|
||||
var responseMessage = new ResponseMessage();
|
||||
|
||||
var model = new
|
||||
{
|
||||
request = requestMessage
|
||||
};
|
||||
|
||||
if (original.BodyData?.DetectedBodyType != null)
|
||||
{
|
||||
responseMessage.BodyData = TransformBodyData(transformerContext, model, original.BodyData, useTransformerForBodyAsFile);
|
||||
|
||||
if (original.BodyData.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
|
||||
}
|
||||
}
|
||||
|
||||
responseMessage.FaultType = original.FaultType;
|
||||
responseMessage.FaultPercentage = original.FaultPercentage;
|
||||
|
||||
responseMessage.Headers = TransformHeaders(transformerContext, model, original.Headers);
|
||||
|
||||
switch (original.StatusCode)
|
||||
{
|
||||
case int statusCodeAsInteger:
|
||||
responseMessage.StatusCode = statusCodeAsInteger;
|
||||
break;
|
||||
|
||||
case string statusCodeAsString:
|
||||
responseMessage.StatusCode = transformerContext.ParseAndRender(statusCodeAsString, model);
|
||||
break;
|
||||
}
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
private static IBodyData TransformBodyData(ITransformerContext transformerContext, object model, IBodyData original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
switch (original?.DetectedBodyType)
|
||||
{
|
||||
case BodyType.Json:
|
||||
return TransformBodyAsJson(transformerContext, model, original);
|
||||
|
||||
case BodyType.File:
|
||||
return TransformBodyAsFile(transformerContext, model, original, useTransformerForBodyAsFile);
|
||||
|
||||
case BodyType.String:
|
||||
return TransformBodyAsString(transformerContext, model, original);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static IDictionary<string, WireMockList<string>> TransformHeaders(ITransformerContext transformerContext, object model, IDictionary<string, WireMockList<string>> original)
|
||||
{
|
||||
if (original == null)
|
||||
{
|
||||
return new Dictionary<string, WireMockList<string>>();
|
||||
}
|
||||
|
||||
var newHeaders = new Dictionary<string, WireMockList<string>>();
|
||||
foreach (var header in original)
|
||||
{
|
||||
var headerKey = transformerContext.ParseAndRender(header.Key, model);
|
||||
var templateHeaderValues = header.Value.Select(text => transformerContext.ParseAndRender(text, model)).ToArray();
|
||||
|
||||
newHeaders.Add(headerKey, new WireMockList<string>(templateHeaderValues));
|
||||
}
|
||||
|
||||
return newHeaders;
|
||||
}
|
||||
|
||||
private static IBodyData TransformBodyAsJson(ITransformerContext handlebarsContext, object model, IBodyData original)
|
||||
{
|
||||
JToken jToken;
|
||||
switch (original.BodyAsJson)
|
||||
{
|
||||
case JObject bodyAsJObject:
|
||||
jToken = bodyAsJObject.DeepClone();
|
||||
WalkNode(handlebarsContext, jToken, model);
|
||||
break;
|
||||
|
||||
case Array bodyAsArray:
|
||||
jToken = JArray.FromObject(bodyAsArray);
|
||||
WalkNode(handlebarsContext, jToken, model);
|
||||
break;
|
||||
|
||||
case string bodyAsString:
|
||||
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, model);
|
||||
break;
|
||||
|
||||
default:
|
||||
jToken = JObject.FromObject(original.BodyAsJson);
|
||||
WalkNode(handlebarsContext, jToken, model);
|
||||
break;
|
||||
}
|
||||
|
||||
return new BodyData
|
||||
{
|
||||
Encoding = original.Encoding,
|
||||
DetectedBodyType = original.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.DetectedBodyTypeFromContentType,
|
||||
BodyAsJson = jToken
|
||||
};
|
||||
}
|
||||
|
||||
private static JToken ReplaceSingleNode(ITransformerContext handlebarsContext, string stringValue, object model)
|
||||
{
|
||||
string transformedString = handlebarsContext.ParseAndRender(stringValue, model);
|
||||
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
const string property = "_";
|
||||
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
|
||||
JToken node = dummy[property];
|
||||
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
|
||||
return dummy[property];
|
||||
}
|
||||
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
private static void WalkNode(ITransformerContext handlebarsContext, JToken node, object model)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child.Value, model);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(handlebarsContext, child, model);
|
||||
}
|
||||
}
|
||||
else if (node.Type == JTokenType.String)
|
||||
{
|
||||
// In case of string, try to transform the value.
|
||||
string stringValue = node.Value<string>();
|
||||
if (string.IsNullOrEmpty(stringValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string transformedString = handlebarsContext.ParseAndRender(stringValue, model);
|
||||
if (!string.Equals(stringValue, transformedString))
|
||||
{
|
||||
ReplaceNodeValue(node, transformedString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ReplaceNodeValue(JToken node, string stringValue)
|
||||
{
|
||||
if (bool.TryParse(stringValue, out bool valueAsBoolean))
|
||||
{
|
||||
node.Replace(valueAsBoolean);
|
||||
return;
|
||||
}
|
||||
|
||||
JToken value;
|
||||
try
|
||||
{
|
||||
// Try to convert this string into a JsonObject
|
||||
value = JToken.Parse(stringValue);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and just keep string value and convert to JToken
|
||||
value = stringValue;
|
||||
}
|
||||
|
||||
node.Replace(value);
|
||||
}
|
||||
|
||||
private static IBodyData TransformBodyAsString(ITransformerContext handlebarsContext, object model, IBodyData original)
|
||||
{
|
||||
return new BodyData
|
||||
{
|
||||
Encoding = original.Encoding,
|
||||
DetectedBodyType = original.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = handlebarsContext.ParseAndRender(original.BodyAsString, model)
|
||||
};
|
||||
}
|
||||
|
||||
private static IBodyData TransformBodyAsFile(ITransformerContext handlebarsContext, object model, IBodyData original, bool useTransformerForBodyAsFile)
|
||||
{
|
||||
string transformedBodyAsFilename = handlebarsContext.ParseAndRender(original.BodyAsFile, model);
|
||||
|
||||
if (!useTransformerForBodyAsFile)
|
||||
{
|
||||
return new BodyData
|
||||
{
|
||||
DetectedBodyType = original.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.DetectedBodyTypeFromContentType,
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = handlebarsContext.FileSystemHandler.ReadResponseBodyAsString(transformedBodyAsFilename);
|
||||
|
||||
return new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = original.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = handlebarsContext.ParseAndRender(text, model),
|
||||
BodyAsFile = transformedBodyAsFilename
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@
|
||||
<PackageReference Include="Microsoft.Owin" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.0.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
<PackageReference Include="Scriban.Signed" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
@@ -121,12 +121,12 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.1.1" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.1.1" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.1.1" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.1.1" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.1.1" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.1.1" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.1.9" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.1.9" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.1.9" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.1.9" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.1.9" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.1.9" />
|
||||
|
||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using NFluent;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Http;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
@@ -28,7 +29,7 @@ namespace WireMock.Net.Tests.Http
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void HttpRequestMessageHelper_Create_Bytes()
|
||||
public async Task HttpRequestMessageHelper_Create_Bytes()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
@@ -46,7 +47,7 @@ namespace WireMock.Net.Tests.Http
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void HttpRequestMessageHelper_Create_Json()
|
||||
public async Task HttpRequestMessageHelper_Create_Json()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
@@ -64,7 +65,7 @@ namespace WireMock.Net.Tests.Http
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void HttpRequestMessageHelper_Create_Json_With_ContentType_ApplicationJson()
|
||||
public async Task HttpRequestMessageHelper_Create_Json_With_ContentType_ApplicationJson()
|
||||
{
|
||||
// Assign
|
||||
var headers = new Dictionary<string, string[]> { { "Content-Type", new[] { "application/json" } } };
|
||||
@@ -84,7 +85,7 @@ namespace WireMock.Net.Tests.Http
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void HttpRequestMessageHelper_Create_Json_With_ContentType_ApplicationJson_UTF8()
|
||||
public async Task HttpRequestMessageHelper_Create_Json_With_ContentType_ApplicationJson_UTF8()
|
||||
{
|
||||
// Assign
|
||||
var headers = new Dictionary<string, string[]> { { "Content-Type", new[] { "application/json; charset=utf-8" } } };
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace WireMock.Net.Tests
|
||||
public class ObservableLogEntriesTest
|
||||
{
|
||||
[Fact]
|
||||
public async void WireMockServer_LogEntriesChanged_WithException_Should_LogError()
|
||||
public async Task WireMockServer_LogEntriesChanged_WithException_Should_LogError()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/log_{Guid.NewGuid()}";
|
||||
@@ -48,7 +48,7 @@ namespace WireMock.Net.Tests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockServer_LogEntriesChanged()
|
||||
public async Task WireMockServer_LogEntriesChanged()
|
||||
{
|
||||
// Assign
|
||||
string path = $"/log_{Guid.NewGuid()}";
|
||||
|
||||
@@ -13,7 +13,6 @@ using WireMock.Matchers;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
using FluentAssertions;
|
||||
using WireMock.Handlers;
|
||||
@@ -78,7 +77,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockMiddleware_Invoke_NoMatch()
|
||||
public async Task WireMockMiddleware_Invoke_NoMatch()
|
||||
{
|
||||
// Act
|
||||
await _sut.Invoke(_contextMock.Object);
|
||||
@@ -91,7 +90,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockMiddleware_Invoke_IsAdminInterface_EmptyHeaders_401()
|
||||
public async Task WireMockMiddleware_Invoke_IsAdminInterface_EmptyHeaders_401()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
|
||||
@@ -114,7 +113,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockMiddleware_Invoke_IsAdminInterface_MissingHeader_401()
|
||||
public async Task WireMockMiddleware_Invoke_IsAdminInterface_MissingHeader_401()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]> { { "h", new[] { "x" } } });
|
||||
@@ -137,7 +136,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockMiddleware_Invoke_RequestLogExpirationDurationIsDefined()
|
||||
public async Task WireMockMiddleware_Invoke_RequestLogExpirationDurationIsDefined()
|
||||
{
|
||||
// Assign
|
||||
_optionsMock.SetupGet(o => o.RequestLogExpirationDuration).Returns(1);
|
||||
@@ -147,7 +146,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockMiddleware_Invoke_Mapping_Has_ProxyAndRecordSettings_And_SaveMapping_Is_True()
|
||||
public async Task WireMockMiddleware_Invoke_Mapping_Has_ProxyAndRecordSettings_And_SaveMapping_Is_True()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
|
||||
@@ -177,7 +176,8 @@ namespace WireMock.Net.Tests.Owin
|
||||
_mappingMock.SetupGet(m => m.Provider).Returns(responseBuilder);
|
||||
_mappingMock.SetupGet(m => m.Settings).Returns(settings);
|
||||
|
||||
_mappingMock.Setup(m => m.ProvideResponseAsync(It.IsAny<RequestMessage>())).ReturnsAsync(new ResponseMessage());
|
||||
var newMappingFromProxy = new Mapping(Guid.NewGuid(), "", null, settings, Request.Create(), Response.Create(), 0, null, null, null, null, null);
|
||||
_mappingMock.Setup(m => m.ProvideResponseAsync(It.IsAny<RequestMessage>())).ReturnsAsync((new ResponseMessage(), newMappingFromProxy));
|
||||
|
||||
var requestBuilder = Request.Create().UsingAnyMethod();
|
||||
_mappingMock.SetupGet(m => m.RequestMatcher).Returns(requestBuilder);
|
||||
@@ -195,7 +195,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void WireMockMiddleware_Invoke_Mapping_Has_ProxyAndRecordSettings_And_SaveMapping_Is_False_But_WireMockServerSettings_SaveMapping_Is_True()
|
||||
public async Task WireMockMiddleware_Invoke_Mapping_Has_ProxyAndRecordSettings_And_SaveMapping_Is_False_But_WireMockServerSettings_SaveMapping_Is_True()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
|
||||
@@ -230,7 +230,8 @@ namespace WireMock.Net.Tests.Owin
|
||||
_mappingMock.SetupGet(m => m.Provider).Returns(responseBuilder);
|
||||
_mappingMock.SetupGet(m => m.Settings).Returns(settings);
|
||||
|
||||
_mappingMock.Setup(m => m.ProvideResponseAsync(It.IsAny<RequestMessage>())).ReturnsAsync(new ResponseMessage());
|
||||
var newMappingFromProxy = new Mapping(Guid.NewGuid(), "", null, settings, Request.Create(), Response.Create(), 0, null, null, null, null, null);
|
||||
_mappingMock.Setup(m => m.ProvideResponseAsync(It.IsAny<RequestMessage>())).ReturnsAsync((new ResponseMessage(), newMappingFromProxy));
|
||||
|
||||
var requestBuilder = Request.Create().UsingAnyMethod();
|
||||
_mappingMock.SetupGet(m => m.RequestMatcher).Returns(requestBuilder);
|
||||
|
||||
@@ -209,13 +209,15 @@ namespace WireMock.Net.Tests.RequestMatchers
|
||||
Check.That(score).IsEqualTo(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestMessageBodyMatcher_GetMatchingScore_BodyAsBytes_IObjectMatcher()
|
||||
[Theory]
|
||||
[InlineData(new byte[] { 1 })]
|
||||
[InlineData(new byte[] { 48 })]
|
||||
public void RequestMessageBodyMatcher_GetMatchingScore_BodyAsBytes_IObjectMatcher(byte[] bytes)
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsBytes = new byte[] { 1 },
|
||||
BodyAsBytes = bytes,
|
||||
DetectedBodyType = BodyType.Bytes
|
||||
};
|
||||
var objectMatcherMock = new Mock<IObjectMatcher>();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using NFluent;
|
||||
using System;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
@@ -54,6 +55,25 @@ namespace WireMock.Net.Tests
|
||||
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()
|
||||
{
|
||||
@@ -288,17 +308,20 @@ namespace WireMock.Net.Tests
|
||||
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Request_WithBodyAsBytes_ExactObjectMatcher_true()
|
||||
[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 = { 123 };
|
||||
byte[] body = bytes;
|
||||
var requestBuilder = Request.Create().UsingAnyMethod().WithBody(body);
|
||||
|
||||
var bodyData = new BodyData
|
||||
{
|
||||
BodyAsBytes = new byte[] { 123 },
|
||||
DetectedBodyType = BodyType.Bytes
|
||||
BodyAsBytes = bytes,
|
||||
DetectedBodyType = detectedBodyType
|
||||
};
|
||||
|
||||
// Act
|
||||
@@ -306,7 +329,7 @@ namespace WireMock.Net.Tests
|
||||
|
||||
// Assert
|
||||
var requestMatchResult = new RequestMatchResult();
|
||||
Check.That(requestBuilder.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
|
||||
requestBuilder.GetMatchingScore(request, requestMatchResult).Should().Be(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,13 +18,13 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var responseMessage = new ResponseMessage { StatusCode = 500 };
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", "::1");
|
||||
|
||||
var response = Response.Create(() => responseMessage);
|
||||
var responseBuilder = Response.Create(() => responseMessage);
|
||||
|
||||
// Act
|
||||
var providedResponse = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(providedResponse).Equals(responseMessage);
|
||||
Check.That(response.Message).Equals(responseMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,15 +40,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.String, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.String, Encoding.ASCII);
|
||||
|
||||
// act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// then
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("01");
|
||||
Check.That(responseMessage.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(responseMessage.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("01");
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -62,15 +62,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.SameAsSource, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.SameAsSource, Encoding.ASCII);
|
||||
|
||||
// act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// then
|
||||
Check.That(responseMessage.BodyData.BodyAsBytes).ContainsExactly(new byte[] { 48, 49 });
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsNull();
|
||||
Check.That(responseMessage.BodyData.Encoding).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).ContainsExactly(new byte[] { 48, 49 });
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response.Message.BodyData.Encoding).IsNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -84,14 +84,14 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create().WithBody("test", null, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBody("test", null, Encoding.ASCII);
|
||||
|
||||
// act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// then
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -106,14 +106,14 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
object x = new { value = "test" };
|
||||
var response = Response.Create().WithBodyAsJson(x, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBodyAsJson(x, Encoding.ASCII);
|
||||
|
||||
// act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// then
|
||||
Check.That(responseMessage.BodyData.BodyAsJson).Equals(x);
|
||||
Check.That(responseMessage.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
Check.That(response.Message.BodyData.BodyAsJson).Equals(x);
|
||||
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -128,14 +128,14 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);
|
||||
|
||||
object x = new { message = "Hello" };
|
||||
var response = Response.Create().WithBodyAsJson(x, true);
|
||||
var responseBuilder = Response.Create().WithBodyAsJson(x, true);
|
||||
|
||||
// act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// then
|
||||
Check.That(responseMessage.BodyData.BodyAsJson).Equals(x);
|
||||
Check.That(responseMessage.BodyData.BodyAsJsonIndented).IsEqualTo(true);
|
||||
Check.That(response.Message.BodyData.BodyAsJson).Equals(x);
|
||||
Check.That(response.Message.BodyData.BodyAsJsonIndented).IsEqualTo(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -144,16 +144,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create().WithBody("r", BodyDestinationFormat.SameAsSource, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBody("r", BodyDestinationFormat.SameAsSource, Encoding.ASCII);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("r");
|
||||
Check.That(responseMessage.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("r");
|
||||
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -162,16 +162,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create().WithBody("r", BodyDestinationFormat.Bytes, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBody("r", BodyDestinationFormat.Bytes, Encoding.ASCII);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsBytes).IsNotNull();
|
||||
Check.That(responseMessage.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).IsNotNull();
|
||||
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -180,16 +180,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create().WithBody("{ \"value\": 42 }", BodyDestinationFormat.Json, Encoding.ASCII);
|
||||
var responseBuilder = Response.Create().WithBody("{ \"value\": 42 }", BodyDestinationFormat.Json, Encoding.ASCII);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(((dynamic)responseMessage.BodyData.BodyAsJson).value).Equals(42);
|
||||
Check.That(responseMessage.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(((dynamic)response.Message.BodyData.BodyAsJson).value).Equals(42);
|
||||
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -198,23 +198,52 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithStatusCode(500)
|
||||
.WithHeader("H1", "X1")
|
||||
.WithHeader("H2", "X2")
|
||||
.WithBody(req => $"path: {req.Path}");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("path: /test");
|
||||
Check.That(responseMessage.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(responseMessage.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
|
||||
Check.That(responseMessage.StatusCode).IsEqualTo(500);
|
||||
Check.That(responseMessage.Headers["H1"].ToString()).IsEqualTo("X1");
|
||||
Check.That(responseMessage.Headers["H2"].ToString()).IsEqualTo("X2");
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test");
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
|
||||
Check.That(response.Message.StatusCode).IsEqualTo(500);
|
||||
Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1");
|
||||
Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_WithBody_FuncAsync()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithStatusCode(500)
|
||||
.WithHeader("H1", "X1")
|
||||
.WithHeader("H2", "X2")
|
||||
.WithBody(async req =>
|
||||
{
|
||||
await Task.Delay(1);
|
||||
return $"path: {req.Path}";
|
||||
});
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test");
|
||||
Check.That(response.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response.Message.BodyData.BodyAsJson).IsNull();
|
||||
Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage);
|
||||
Check.That(response.Message.StatusCode).IsEqualTo(500);
|
||||
Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1");
|
||||
Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -227,25 +256,25 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request1 = new RequestMessage(new UrlDetails($"http://localhost/test?id={request1Id}"), "GET", ClientIp);
|
||||
var request2 = new RequestMessage(new UrlDetails($"http://localhost/test?id={request2Id}"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithStatusCode(200)
|
||||
.WithBodyAsJson(JObject.Parse("{ \"id\": \"{{request.query.id}}\" }"))
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response1Message = await response.ProvideResponseAsync(request1, _settings);
|
||||
var response2Message = await response.ProvideResponseAsync(request2, _settings);
|
||||
var response1 = await responseBuilder.ProvideResponseAsync(request1, _settings);
|
||||
var response2 = await responseBuilder.ProvideResponseAsync(request2, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(((JToken)response1Message.BodyData.BodyAsJson).SelectToken("id")?.Value<int>()).IsEqualTo(request1Id);
|
||||
Check.That(response1Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response1Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response1Message.StatusCode).IsEqualTo(200);
|
||||
Check.That(((JToken)response1.Message.BodyData.BodyAsJson).SelectToken("id")?.Value<int>()).IsEqualTo(request1Id);
|
||||
Check.That(response1.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response1.Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response1.Message.StatusCode).IsEqualTo(200);
|
||||
|
||||
Check.That(((JToken)response2Message.BodyData.BodyAsJson).SelectToken("id")?.Value<int>()).IsEqualTo(request2Id);
|
||||
Check.That(response2Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response2Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response2Message.StatusCode).IsEqualTo(200);
|
||||
Check.That(((JToken)response2.Message.BodyData.BodyAsJson).SelectToken("id")?.Value<int>()).IsEqualTo(request2Id);
|
||||
Check.That(response2.Message.BodyData.BodyAsBytes).IsNull();
|
||||
Check.That(response2.Message.BodyData.BodyAsString).IsNull();
|
||||
Check.That(response2.Message.StatusCode).IsEqualTo(200);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -256,12 +285,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "PUT", ClientIp, bodyDataAsFile);
|
||||
|
||||
var response = Response.Create().WithStatusCode(200).WithBody(fileContents);
|
||||
var responseBuilder = Response.Create().WithStatusCode(200).WithBody(fileContents);
|
||||
|
||||
var provideResponseAsync = await response.ProvideResponseAsync(request1, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request1, _settings);
|
||||
|
||||
Check.That(provideResponseAsync.StatusCode).IsEqualTo(200);
|
||||
Check.That(provideResponseAsync.BodyData.BodyAsString).Contains(fileContents);
|
||||
Check.That(response.Message.StatusCode).IsEqualTo(200);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Contains(fileContents);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -272,12 +301,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "GET", ClientIp, bodyDataAsFile);
|
||||
|
||||
var response = Response.Create().WithStatusCode(200).WithBody(fileContents);
|
||||
var responseBuilder = Response.Create().WithStatusCode(200).WithBody(fileContents);
|
||||
|
||||
var provideResponseAsync = await response.ProvideResponseAsync(request1, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request1, _settings);
|
||||
|
||||
Check.That(provideResponseAsync.StatusCode).IsEqualTo(200);
|
||||
Check.That(provideResponseAsync.BodyData.BodyAsString).Contains(fileContents);
|
||||
Check.That(response.Message.StatusCode).IsEqualTo(200);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Contains(fileContents);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -288,12 +317,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "DELETE", ClientIp, bodyDataAsFile);
|
||||
|
||||
var response = Response.Create().WithStatusCode(200).WithBody("File deleted.");
|
||||
var responseBuilder = Response.Create().WithStatusCode(200).WithBody("File deleted.");
|
||||
|
||||
var provideResponseAsync = await response.ProvideResponseAsync(request1, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request1, _settings);
|
||||
|
||||
Check.That(provideResponseAsync.StatusCode).IsEqualTo(200);
|
||||
Check.That(provideResponseAsync.BodyData.BodyAsString).Contains("File deleted.");
|
||||
Check.That(response.Message.StatusCode).IsEqualTo(200);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Contains("File deleted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using WireMock.Handlers;
|
||||
@@ -31,7 +33,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithCallback(async request =>
|
||||
{
|
||||
await Task.Delay(1);
|
||||
@@ -48,11 +50,11 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
});
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
response.Message.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
response.Message.StatusCode.Should().Be(302);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -60,7 +62,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
@@ -72,11 +74,73 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
});
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
response.Message.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
response.Message.StatusCode.Should().Be(302);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_WithCallback_ShouldUseStatusCodeAndHeaderInTheCallback()
|
||||
{
|
||||
// Assign
|
||||
var header = "X-UserId";
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var responseBuilder = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = request.Path + "Bar"
|
||||
},
|
||||
StatusCode = HttpStatusCode.Accepted,
|
||||
Headers = new Dictionary<string, WireMockList<string>>
|
||||
{
|
||||
{ header, new WireMockList<string>("Stef") }
|
||||
}
|
||||
});
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
response.Message.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
response.Message.StatusCode.Should().Be(HttpStatusCode.Accepted);
|
||||
response.Message.Headers[header].Should().ContainSingle("Stef");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_WithCallback_And_Additional_WithStatusCode_And_WithHeader_ShouldUseAdditional()
|
||||
{
|
||||
// Assign
|
||||
var header = "X-UserId";
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var responseBuilder = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = request.Path + "Bar"
|
||||
},
|
||||
StatusCode = HttpStatusCode.NotFound,
|
||||
Headers = new Dictionary<string, WireMockList<string>>
|
||||
{
|
||||
{ header, new WireMockList<string>("NA") }
|
||||
}
|
||||
})
|
||||
.WithStatusCode(HttpStatusCode.Accepted)
|
||||
.WithHeader(header, "Stef");
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
response.Message.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
response.Message.StatusCode.Should().Be(HttpStatusCode.Accepted);
|
||||
response.Message.Headers[header].Should().ContainSingle("Stef");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -84,7 +148,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithCallback(request => new ResponseMessage
|
||||
{
|
||||
BodyData = new BodyData
|
||||
@@ -97,11 +161,11 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(requestMessage, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(requestMessage, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
responseMessage.StatusCode.Should().Be(302);
|
||||
response.Message.BodyData.BodyAsString.Should().Be("/fooBar");
|
||||
response.Message.StatusCode.Should().Be(302);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/fault"), "GET", ClientIp);
|
||||
|
||||
// Act
|
||||
var response = Response.Create().WithFault(faultType);
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var responseBuilder = Response.Create().WithFault(faultType);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.FaultType.Should().Be(faultType);
|
||||
responseMessage.FaultPercentage.Should().BeNull();
|
||||
response.Message.FaultType.Should().Be(faultType);
|
||||
response.Message.FaultPercentage.Should().BeNull();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -37,12 +37,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/fault"), "GET", ClientIp);
|
||||
|
||||
// Act
|
||||
var response = Response.Create().WithFault(faultType, percentage);
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var responseBuilder = Response.Create().WithFault(faultType, percentage);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.FaultType.Should().Be(faultType);
|
||||
responseMessage.FaultPercentage.Should().Be(percentage);
|
||||
response.Message.FaultType.Should().Be(faultType);
|
||||
response.Message.FaultPercentage.Should().Be(percentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,100 +1,99 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using HandlebarsDotNet;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsFileTests
|
||||
{
|
||||
private readonly Mock<IFileSystemHandler> _filesystemHandlerMock;
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
public ResponseWithHandlebarsFileTests()
|
||||
{
|
||||
_filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
_filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("abc");
|
||||
|
||||
_settings.FileSystemHandler = _filesystemHandlerMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_File()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Data = "{{File \"x.json\"}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
Check.That(j["Data"].Value<string>()).Equals("abc");
|
||||
|
||||
// Verify
|
||||
_filesystemHandlerMock.Verify(fs => fs.ReadResponseBodyAsString("x.json"), Times.Once);
|
||||
_filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_File_Replace()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234?id=x"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Data = "{{File \"{{request.query.id}}.json\"}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
Check.That(j["Data"].Value<string>()).Equals("abc");
|
||||
|
||||
// Verify
|
||||
_filesystemHandlerMock.Verify(fs => fs.ReadResponseBodyAsString("x.json"), Times.Once);
|
||||
_filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponseAsync_Handlebars_File_WithMissingArgument_Throws_HandlebarsException()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Data = "{{File}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<HandlebarsException>();
|
||||
|
||||
// Verify
|
||||
_filesystemHandlerMock.Verify(fs => fs.ReadResponseBodyAsString(It.IsAny<string>()), Times.Never);
|
||||
_filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsFileTests
|
||||
{
|
||||
private readonly Mock<IFileSystemHandler> _filesystemHandlerMock;
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
public ResponseWithHandlebarsFileTests()
|
||||
{
|
||||
_filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
_filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("abc");
|
||||
|
||||
_settings.FileSystemHandler = _filesystemHandlerMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_File()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Data = "{{File \"x.json\"}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Data"].Value<string>()).Equals("abc");
|
||||
|
||||
// Verify
|
||||
_filesystemHandlerMock.Verify(fs => fs.ReadResponseBodyAsString("x.json"), Times.Once);
|
||||
_filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_File_Replace()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234?id=x"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Data = "{{File \"{{request.query.id}}.json\"}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Data"].Value<string>()).Equals("abc");
|
||||
|
||||
// Verify
|
||||
_filesystemHandlerMock.Verify(fs => fs.ReadResponseBodyAsString("x.json"), Times.Once);
|
||||
_filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponseAsync_Handlebars_File_WithMissingArgument_Throws_HandlebarsException()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Data = "{{File}}"
|
||||
})
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<HandlebarsException>();
|
||||
|
||||
// Verify
|
||||
_filesystemHandlerMock.Verify(fs => fs.ReadResponseBodyAsString(It.IsAny<string>()), Times.Never);
|
||||
_filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,15 +34,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{String.Uppercase request.body}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("ABC");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("ABC");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,16 +71,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"]["Name"].ToString()).Equals("Acme Co");
|
||||
}
|
||||
@@ -97,16 +97,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"..Price\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["x"].Value<long>()).Equals(99);
|
||||
}
|
||||
|
||||
@@ -151,16 +151,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals($"{{{Environment.NewLine} \"Name\": \"Acme Co\",{Environment.NewLine} \"Products\": [{Environment.NewLine} {{{Environment.NewLine} \"Name\": \"Anvil\",{Environment.NewLine} \"Price\": 50{Environment.NewLine} }}{Environment.NewLine} ]{Environment.NewLine}}}");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals($"{{{Environment.NewLine} \"Name\": \"Acme Co\",{Environment.NewLine} \"Products\": [{Environment.NewLine} {{{Environment.NewLine} \"Name\": \"Anvil\",{Environment.NewLine} \"Price\": 50{Environment.NewLine} }}{Environment.NewLine} ]{Environment.NewLine}}}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -204,16 +204,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{JsonPath.SelectToken request.bodyAsJson \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals($"{{{Environment.NewLine} \"Name\": \"Acme Co\",{Environment.NewLine} \"Products\": [{Environment.NewLine} {{{Environment.NewLine} \"Name\": \"Anvil\",{Environment.NewLine} \"Price\": 50{Environment.NewLine} }}{Environment.NewLine} ]{Environment.NewLine}}}");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals($"{{{Environment.NewLine} \"Name\": \"Acme Co\",{Environment.NewLine} \"Products\": [{Environment.NewLine} {{{Environment.NewLine} \"Name\": \"Anvil\",{Environment.NewLine} \"Price\": 50{Environment.NewLine} }}{Environment.NewLine} ]{Environment.NewLine}}}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -257,16 +257,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.body \"$..Products[?(@.Price >= 50)].Name\"}}{{#each this}}%{{@index}}:{{this}}%{{/each}}{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("%0:Anvil%%1:Elbow Grease%");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("%0:Anvil%%1:Elbow Grease%");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -310,16 +310,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.bodyAsJson \"$..Products[?(@.Price >= 50)].Name\"}}{{#each this}}%{{@index}}:{{this}}%{{/each}}{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("%0:Anvil%%1:Elbow Grease%");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("%0:Anvil%%1:Elbow Grease%");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -339,13 +339,13 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.body \"$..Products[?(@.Price >= 50)].Name\"}}{{id}} {{value}},{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<ArgumentNullException>();
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -364,15 +364,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, bodyData);
|
||||
|
||||
string jsonPath = "\"$.MyUniqueNumber\"";
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{JsonPath.SelectToken request.body " + jsonPath + "}}\\test.json"); // why use a \\ here ?
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
|
||||
Check.That(response.Message.BodyData.BodyAsFile).Equals(@"c:\1\test.json");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,249 +1,249 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using HandlebarsDotNet;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsLinqTests
|
||||
{
|
||||
private readonly Mock<IFileSystemHandler> _filesystemHandlerMock;
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
|
||||
public ResponseWithHandlebarsLinqTests()
|
||||
{
|
||||
_filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
_filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("abc");
|
||||
|
||||
_settings.FileSystemHandler = _filesystemHandlerMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String0()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData();
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234/pathtest"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.Path 'it'}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("/pathtest");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String1()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 'it.Name + \"_123\"' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("Test_123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String2()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 'new(it.Name + \"_123\" as N, it.Id as I)' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("{ N = Test_123, I = 9 }");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq2_Object()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{#Linq request.bodyAsJson 'new(it.Name + \"_123\" as N, it.Id as I)' }}{{this}}{{/Linq}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("{ N = Test_123, I = 9 }");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq_Throws_ArgumentException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new { x = "x" },
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 1}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<ArgumentException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_Throws_ArgumentNullException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData();
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.body 'Name'}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_Throws_HandlebarsException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData();
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson}} ''" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<HandlebarsException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_ParseError_Throws_ExceptionMessage()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson '---' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Func<Task> a = async () => await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
a.Should().Throw<HandlebarsException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq2_ParseError_Throws_ExceptionMessage()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{#Linq request.bodyAsJson '---' }}{{this}}{{/Linq}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Func<Task> a = async () => await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
a.Should().Throw<HandlebarsException>();
|
||||
}
|
||||
}
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders
|
||||
{
|
||||
public class ResponseWithHandlebarsLinqTests
|
||||
{
|
||||
private readonly Mock<IFileSystemHandler> _filesystemHandlerMock;
|
||||
private readonly WireMockServerSettings _settings = new WireMockServerSettings();
|
||||
|
||||
public ResponseWithHandlebarsLinqTests()
|
||||
{
|
||||
_filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
_filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny<string>())).Returns("abc");
|
||||
|
||||
_settings.FileSystemHandler = _filesystemHandlerMock.Object;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String0()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData();
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234/pathtest"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.Path 'it'}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("/pathtest");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String1()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 'it.Name + \"_123\"' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("Test_123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String2()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 'new(it.Name + \"_123\" as N, it.Id as I)' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("{ N = Test_123, I = 9 }");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq2_Object()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{#Linq request.bodyAsJson 'new(it.Name + \"_123\" as N, it.Id as I)' }}{{this}}{{/Linq}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("{ N = Test_123, I = 9 }");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq_Throws_ArgumentException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new { x = "x" },
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 1}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<ArgumentException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_Throws_ArgumentNullException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData();
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.body 'Name'}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_Throws_HandlebarsException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData();
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson}} ''" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<HandlebarsException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_ParseError_Throws_ExceptionMessage()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson '---' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Func<Task> a = async () => await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
a.Should().Throw<HandlebarsException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq2_ParseError_Throws_ExceptionMessage()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
},
|
||||
DetectedBodyType = BodyType.Json
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{#Linq request.bodyAsJson '---' }}{{this}}{{/Linq}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Func<Task> a = async () => await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
a.Should().Throw<HandlebarsException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Text = "{{Random Type=\"Text\" Min=8 Max=20}}",
|
||||
@@ -43,10 +43,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Text"].Value<string>()).IsNotEmpty();
|
||||
Check.That(j["Integer"].Value<int>()).IsEqualTo(1000);
|
||||
Check.That(j["Long"].Value<long>()).IsStrictlyGreaterThan(77777777).And.IsStrictlyLessThan(99999999);
|
||||
@@ -58,7 +58,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Value = "{{Random Type=\"Boolean\"}}"
|
||||
@@ -66,10 +66,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Value"].Type).IsEqualTo(JTokenType.Boolean);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Guid1 = "{{Random Type=\"Guid\" Uppercase=false}}",
|
||||
@@ -88,10 +88,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
string guid1 = j["Guid1"].Value<string>();
|
||||
Check.That(guid1.ToUpper()).IsNotEqualTo(guid1);
|
||||
string guid2 = j["Guid2"].Value<string>();
|
||||
@@ -104,7 +104,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
StringValue = "{{Random Type=\"StringList\" Values=[\"a\", \"b\", \"c\"]}}"
|
||||
@@ -112,10 +112,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
string value = j["StringValue"].Value<string>();
|
||||
Check.That(new[] { "a", "b", "c" }.Contains(value)).IsTrue();
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Integer = "{{#Random Type=\"Integer\" Min=10000000 Max=99999999}}{{this}}{{/Random}}",
|
||||
@@ -134,10 +134,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Integer"].Value<int>()).IsStrictlyGreaterThan(10000000).And.IsStrictlyLessThan(99999999);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,15 +35,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{Regex.Match request.body \"^(\\w+)$\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("abc");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("abc");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -54,34 +54,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{Regex.Match request.body \"^?0$\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_RegexMatch_NoMatch_WithDefaultValue()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "abc", DetectedBodyType = BodyType.String };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{Regex.Match request.body \"^?0$\" \"d\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("d");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -92,15 +73,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{this.port}}-{{this.proto}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("5000-https");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("5000-https");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -111,34 +92,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{this}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponseAsync_Handlebars_RegexMatch2_NoMatch_WithDefaultValue()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{{\\test", DetectedBodyType = BodyType.String };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\" \"x\"}}{{this}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("x");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -149,12 +111,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.bodyAsJson \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act and Assert
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<ArgumentNullException>();
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<ArgumentNullException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,16 +46,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/xml")
|
||||
.WithBody("<response>{{XPath.SelectSingleNode request.body \"/todo-list/todo-item[1]\"}}</response>")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
var nav = new XmlDocument { InnerXml = responseMessage.BodyData.BodyAsString }.CreateNavigator();
|
||||
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");
|
||||
@@ -77,16 +77,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/xml")
|
||||
.WithBody("{{XPath.SelectSingleNode request.body \"/todo-list/todo-item[1]/text()\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("abc");
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("abc");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -105,16 +105,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/xml")
|
||||
.WithBody("<response>{{XPath.SelectNodes request.body \"/todo-list/todo-item\"}}</response>")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
var nav = new XmlDocument { InnerXml = responseMessage.BodyData.BodyAsString }.CreateNavigator();
|
||||
var nav = new XmlDocument { InnerXml = response.Message.BodyData.BodyAsString }.CreateNavigator();
|
||||
var nodes = nav.XPath2SelectNodes("/response/todo-item");
|
||||
Check.That(nodes.Count + 1).IsEqualTo(3);
|
||||
}
|
||||
@@ -135,16 +135,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/xml")
|
||||
.WithBody("{{XPath.Evaluate request.body \"boolean(/todo-list[count(todo-item) = 3])\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualIgnoringCase("True");
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsEqualIgnoringCase("True");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -163,16 +163,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithHeader("Content-Type", "application/xml")
|
||||
.WithBody("{{XPath.Evaluate request.body \"string(/todo-list/todo-item[1]/@id)\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo("a1");
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("a1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Number = "{{Xeger.Generate \"[1-9]{1}\\d{3}\"}}",
|
||||
@@ -40,10 +40,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Number"].Value<int>()).IsStrictlyGreaterThan(1000).And.IsStrictlyLessThan(9999);
|
||||
Check.That(j["Postcode"].Value<string>()).IsNotEmpty();
|
||||
}
|
||||
@@ -54,7 +54,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Number = "{{#Xeger.Generate \"[1-9]{1}\\d{3}\"}}{{this}}{{/Xeger.Generate}}",
|
||||
@@ -63,10 +63,10 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyData.BodyAsJson);
|
||||
JObject j = JObject.FromObject(response.Message.BodyData.BodyAsJson);
|
||||
Check.That(j["Number"].Value<int>()).IsStrictlyGreaterThan(1000).And.IsStrictlyLessThan(9999);
|
||||
Check.That(j["Postcode"].Value<string>()).IsNotEmpty();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var response = await builder.ProvideResponseAsync(requestMock, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(response.Headers[headerName].ToString()).Equals(headerValue);
|
||||
Check.That(response.Message.Headers[headerName].ToString()).Equals(headerValue);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -44,7 +44,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var response = await builder.ProvideResponseAsync(requestMock, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(response.Headers[headerName].ToArray()).Equals(headerValues);
|
||||
Check.That(response.Message.Headers[headerName].ToArray()).Equals(headerValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -59,7 +59,7 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Headers["h"]).ContainsExactly("x");
|
||||
Check.That(responseMessage.Message.Headers["h"]).ContainsExactly("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -68,13 +68,13 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
var headers = new Dictionary<string, string[]> { { "h", new[] { "x" } } };
|
||||
var response = Response.Create().WithHeaders(headers);
|
||||
var responseBuilder = Response.Create().WithHeaders(headers);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Headers["h"]).ContainsExactly("x");
|
||||
Check.That(response.Message.Headers["h"]).ContainsExactly("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -83,13 +83,13 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp);
|
||||
var headers = new Dictionary<string, WireMockList<string>> { { "h", new WireMockList<string>("x") } };
|
||||
var response = Response.Create().WithHeaders(headers);
|
||||
var builder = Response.Create().WithHeaders(headers);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await builder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Headers["h"]).ContainsExactly("x");
|
||||
Check.That(response.Message.Headers["h"]).ContainsExactly("x");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,16 +46,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var headers = new Dictionary<string, string[]> { { "Content-Type", new[] { "application/xml" } } };
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}{prepend}/{_guid}{append}"), "POST", ClientIp, new BodyData { DetectedBodyType = BodyType.Json, BodyAsJson = new { a = 1 } }, headers);
|
||||
var response = Response.Create().WithProxy(_server.Urls[0]);
|
||||
var responseBuilder = Response.Create().WithProxy(_server.Urls[0]);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(request.ProxyUrl).IsNotNull();
|
||||
Check.That(responseMessage.BodyData.BodyAsString).IsEqualTo(expectedBody);
|
||||
Check.That(responseMessage.StatusCode).IsEqualTo(201);
|
||||
Check.That(responseMessage.Headers["Content-Type"].ToString()).IsEqualTo("application/json");
|
||||
Check.That(response.Message.BodyData.BodyAsString).IsEqualTo(expectedBody);
|
||||
Check.That(response.Message.StatusCode).IsEqualTo(201);
|
||||
Check.That(response.Message.Headers["Content-Type"].ToString()).IsEqualTo("application/json");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -72,12 +72,12 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
Password = "y"
|
||||
}
|
||||
};
|
||||
var response = Response.Create().WithProxy(settings);
|
||||
var responseBuilder = Response.Create().WithProxy(settings);
|
||||
|
||||
// Act
|
||||
var request = new RequestMessage(new UrlDetails($"{_server.Urls[0]}/{_guid}"), "GET", ClientIp);
|
||||
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request, _settings)).Throws<HttpRequestException>();
|
||||
Check.ThatAsyncCode(() => responseBuilder.ProvideResponseAsync(request, _settings)).Throws<HttpRequestException>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -40,13 +40,13 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "GET", ClientIp);
|
||||
|
||||
var response = Response.Create().WithTransformer(TransformerType.ScribanDotLiquid);
|
||||
var responseBuilder = Response.Create().WithTransformer(TransformerType.ScribanDotLiquid);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.Should().BeNull();
|
||||
response.Message.BodyData.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -60,15 +60,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("test {{request.Url}} {{request.Path}} {{request.Method}}")
|
||||
.WithTransformer(TransformerType.Scriban);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,26 +24,26 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/fault"), "GET", ClientIp);
|
||||
|
||||
// Act
|
||||
var response = Response.Create();
|
||||
var responseBuilder = Response.Create();
|
||||
switch (statusCode)
|
||||
{
|
||||
case string statusCodeAsString:
|
||||
response = response.WithStatusCode(statusCodeAsString);
|
||||
responseBuilder = responseBuilder.WithStatusCode(statusCodeAsString);
|
||||
break;
|
||||
|
||||
case int statusCodeAInteger:
|
||||
response = response.WithStatusCode(statusCodeAInteger);
|
||||
responseBuilder = responseBuilder.WithStatusCode(statusCodeAInteger);
|
||||
break;
|
||||
|
||||
case HttpStatusCode statusCodeAsEnum:
|
||||
response = response.WithStatusCode(statusCodeAsEnum);
|
||||
responseBuilder = responseBuilder.WithStatusCode(statusCodeAsEnum);
|
||||
break;
|
||||
}
|
||||
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settingsMock.Object);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settingsMock.Object);
|
||||
|
||||
// Assert
|
||||
responseMessage.StatusCode.Should().Be(expectedStatusCode);
|
||||
response.Message.StatusCode.Should().Be(expectedStatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,13 +46,13 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "GET", ClientIp);
|
||||
|
||||
var response = Response.Create().WithTransformer(transformerType);
|
||||
var responseBuilder = Response.Create().WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.Should().BeNull();
|
||||
response.Message.BodyData.Should().BeNull();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -69,15 +69,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POSt", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("test {{request.Url}} {{request.Path}} {{request.Method}}")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test http://localhost/foo /foo POSt");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -93,15 +93,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, httpMethod, ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("url={{request.Url}} absoluteurl={{request.AbsoluteUrl}} path={{request.Path}} absolutepath={{request.AbsolutePath}}")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("url=http://localhost/a/b absoluteurl=http://localhost/wiremock/a/b path=/a/b absolutepath=/wiremock/a/b");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("url=http://localhost/a/b absoluteurl=http://localhost/wiremock/a/b path=/a/b absolutepath=/wiremock/a/b");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -111,15 +111,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "POST", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{request.PathSegments.[0]}} {{request.AbsolutePathSegments.[0]}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("a wiremock");
|
||||
}
|
||||
|
||||
[Theory(Skip = "Invalid token `OpenBracket`")]
|
||||
@@ -131,15 +131,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
var urlDetails = UrlUtils.Parse(new Uri("http://localhost/wiremock/a/b"), new PathString("/wiremock"));
|
||||
var request = new RequestMessage(urlDetails, "POST", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{request.PathSegments.[0]}} {{request.AbsolutePathSegments.[0]}}")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("a wiremock");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("a wiremock");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -153,15 +153,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1,2 idx=1 idx=2 keyb=5");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test keya=1,2 idx=1 idx=2 keyb=5");
|
||||
}
|
||||
|
||||
[Theory(Skip = "Invalid token `OpenBracket`")]
|
||||
@@ -177,15 +177,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=1&a=2&b=5"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test keya=1 idx=1 idx=2 keyb=5");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -199,17 +199,17 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithStatusCode("{{request.query.a}}")
|
||||
.WithBody("test")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals("400");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.StatusCode).Equals("400");
|
||||
}
|
||||
|
||||
[Theory(Skip = "WireMockList is not supported by Scriban")]
|
||||
@@ -225,17 +225,17 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithStatusCode("{{request.Query.a}}")
|
||||
.WithBody("test")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals("400");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.StatusCode).Equals("400");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -252,16 +252,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?a=400"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("test")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.StatusCode).Equals(null);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.StatusCode).Equals(null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -275,15 +275,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
|
||||
var responseBuilder = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}").WithBody("test").WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).ContainsExactly("text/plain");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.Headers).ContainsKey("x");
|
||||
Check.That(response.Message.Headers["x"]).ContainsExactly("text/plain");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -297,16 +297,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
|
||||
var responseBuilder = Response.Create().WithHeader("x", "{{request.headers.Content-Type}}", "{{request.url}}").WithBody("test").WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.Headers).ContainsKey("x");
|
||||
Check.That(response.Message.Headers["x"]).Contains("text/plain");
|
||||
Check.That(response.Message.Headers["x"]).Contains("http://localhost/foo");
|
||||
}
|
||||
|
||||
[Theory(Skip = "WireMockList is not supported by Scriban")]
|
||||
@@ -322,16 +322,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body, new Dictionary<string, string[]> { { "Content-Type", new[] { "text/plain" } } });
|
||||
|
||||
var response = Response.Create().WithHeader("x", "{{request.Headers[\"Content-Type\"]}}", "{{request.Url}}").WithBody("test").WithTransformer(transformerType);
|
||||
var responseBuilder = Response.Create().WithHeader("x", "{{request.Headers[\"Content-Type\"]}}", "{{request.Url}}").WithBody("test").WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(responseMessage.Headers).ContainsKey("x");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
|
||||
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test");
|
||||
Check.That(response.Message.Headers).ContainsKey("x");
|
||||
Check.That(response.Message.Headers["x"]).Contains("text/plain");
|
||||
Check.That(response.Message.Headers["x"]).Contains("http://localhost/foo");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -348,15 +348,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("test {{request.Origin}} {{request.Port}} {{request.Protocol}} {{request.Host}}")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("test http://localhost:1234 1234 http localhost");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -375,15 +375,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new { x = "test {{request.Path}}" })
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
|
||||
Check.That(JsonConvert.SerializeObject(response.Message.BodyData.BodyAsJson)).Equals("{\"x\":\"test /foo_object\"}");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -402,15 +402,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_array"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson(new[] { "first", "{{request.path}}", "{{request.bodyAsJson.a}}", "{{request.bodyAsJson.b}}", "last" })
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
|
||||
Check.That(JsonConvert.SerializeObject(response.Message.BodyData.BodyAsJson)).Equals("[\"first\",\"/foo_array\",\"test 1\",\"test 2\",\"last\"]");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -419,15 +419,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithTransformer()
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(response.Message.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
}
|
||||
|
||||
[Theory(Skip = @"Does not work in Scriban --> c:\\[""1""]\\test.xml")]
|
||||
@@ -438,15 +438,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithTransformer(transformerType)
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(response.Message.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -463,17 +463,17 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo?MyUniqueNumber=1"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithTransformer(transformerType, true)
|
||||
.WithBodyFromFile(@"c:\\{{request.query.MyUniqueNumber}}\\test.xml");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(responseMessage.BodyData.DetectedBodyType).Equals(BodyType.String);
|
||||
Check.That(responseMessage.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
|
||||
Check.That(response.Message.BodyData.BodyAsFile).Equals(@"c:\1\test.xml");
|
||||
Check.That(response.Message.BodyData.DetectedBodyType).Equals(BodyType.String);
|
||||
Check.That(response.Message.BodyData.BodyAsString).Equals("<xml MyUniqueNumber=\"1\"></xml>");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -492,15 +492,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson("test")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("\"test\"");
|
||||
Check.That(JsonConvert.SerializeObject(response.Message.BodyData.BodyAsJson)).Equals("\"test\"");
|
||||
}
|
||||
|
||||
[Fact(Skip = "todo...")]
|
||||
@@ -516,15 +516,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson("{{{request.BodyAsJson}}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
|
||||
Check.That(JsonConvert.SerializeObject(response.Message.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
|
||||
}
|
||||
|
||||
[Theory(Skip = "{{{ }}} Does not work in Scriban")]
|
||||
@@ -542,15 +542,15 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBodyAsJson("{{{request.BodyAsJson}}}")
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
Check.That(JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
|
||||
Check.That(JsonConvert.SerializeObject(response.Message.BodyData.BodyAsJson)).Equals("{\"name\":\"WireMock\"}");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
@@ -570,16 +570,16 @@ namespace WireMock.Net.Tests.ResponseBuilders
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo_object"), "POST", ClientIp, bodyData);
|
||||
|
||||
var response = Response.Create()
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{request.Body}}", BodyDestinationFormat.SameAsSource, enc)
|
||||
.WithTransformer(transformerType);
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request, _settings);
|
||||
var response = await responseBuilder.ProvideResponseAsync(request, _settings);
|
||||
|
||||
// Assert
|
||||
responseMessage.BodyData.BodyAsString.Should().Be(text);
|
||||
responseMessage.BodyData.Encoding.Should().Be(enc);
|
||||
response.Message.BodyData.BodyAsString.Should().Be(text);
|
||||
response.Message.BodyData.Encoding.Should().Be(enc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using WireMock.Models;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Serialization;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Serialization
|
||||
@@ -20,12 +24,34 @@ namespace WireMock.Net.Tests.Serialization
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToMappingModel()
|
||||
public void ToMappingModel_With_SingleWebHook()
|
||||
{
|
||||
// Assign
|
||||
var request = Request.Create();
|
||||
var response = Response.Create();
|
||||
var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 0, null, null, null, null);
|
||||
var webhooks = new IWebhook[]
|
||||
{
|
||||
new Webhook
|
||||
{
|
||||
Request = new WebhookRequest
|
||||
{
|
||||
Url = "https://test.com",
|
||||
Headers = new Dictionary<string, WireMockList<string>>
|
||||
{
|
||||
{ "Single", new WireMockList<string>("x") },
|
||||
{ "Multi", new WireMockList<string>("a", "b") }
|
||||
},
|
||||
Method = "post",
|
||||
BodyData = new BodyData
|
||||
{
|
||||
BodyAsString = "b",
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = BodyType.String
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 0, null, null, null, null, webhooks);
|
||||
|
||||
// Act
|
||||
var model = _sut.ToMappingModel(mapping);
|
||||
@@ -33,9 +59,92 @@ namespace WireMock.Net.Tests.Serialization
|
||||
// Assert
|
||||
model.Should().NotBeNull();
|
||||
model.Priority.Should().BeNull();
|
||||
|
||||
model.Response.BodyAsJsonIndented.Should().BeNull();
|
||||
model.Response.UseTransformer.Should().BeNull();
|
||||
model.Response.Headers.Should().BeNull();
|
||||
|
||||
model.Webhooks.Should().BeNull();
|
||||
|
||||
model.Webhook.Request.Method.Should().Be("post");
|
||||
model.Webhook.Request.Url.Should().Be("https://test.com");
|
||||
model.Webhook.Request.Headers.Should().HaveCount(2);
|
||||
model.Webhook.Request.Body.Should().Be("b");
|
||||
model.Webhook.Request.BodyAsJson.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToMappingModel_With_MultipleWebHooks()
|
||||
{
|
||||
// Assign
|
||||
var request = Request.Create();
|
||||
var response = Response.Create();
|
||||
var webhooks = new IWebhook[]
|
||||
{
|
||||
new Webhook
|
||||
{
|
||||
Request = new WebhookRequest
|
||||
{
|
||||
Url = "https://test1.com",
|
||||
Headers = new Dictionary<string, WireMockList<string>>
|
||||
{
|
||||
{ "One", new WireMockList<string>("x") }
|
||||
},
|
||||
Method = "post",
|
||||
BodyData = new BodyData
|
||||
{
|
||||
BodyAsString = "1",
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = BodyType.String
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
new Webhook
|
||||
{
|
||||
Request = new WebhookRequest
|
||||
{
|
||||
Url = "https://test2.com",
|
||||
Headers = new Dictionary<string, WireMockList<string>>
|
||||
{
|
||||
{ "First", new WireMockList<string>("x") },
|
||||
{ "Second", new WireMockList<string>("a", "b") }
|
||||
},
|
||||
Method = "post",
|
||||
BodyData = new BodyData
|
||||
{
|
||||
BodyAsString = "2",
|
||||
DetectedBodyType = BodyType.String,
|
||||
DetectedBodyTypeFromContentType = BodyType.String
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 0, null, null, null, null, webhooks
|
||||
);
|
||||
|
||||
// Act
|
||||
var model = _sut.ToMappingModel(mapping);
|
||||
|
||||
// Assert
|
||||
model.Should().NotBeNull();
|
||||
model.Priority.Should().BeNull();
|
||||
|
||||
model.Response.BodyAsJsonIndented.Should().BeNull();
|
||||
model.Response.UseTransformer.Should().BeNull();
|
||||
model.Response.Headers.Should().BeNull();
|
||||
|
||||
model.Webhook.Should().BeNull();
|
||||
|
||||
model.Webhooks[0].Request.Method.Should().Be("post");
|
||||
model.Webhooks[0].Request.Url.Should().Be("https://test1.com");
|
||||
model.Webhooks[0].Request.Headers.Should().HaveCount(1);
|
||||
model.Webhooks[0].Request.Body.Should().Be("1");
|
||||
|
||||
model.Webhooks[1].Request.Method.Should().Be("post");
|
||||
model.Webhooks[1].Request.Url.Should().Be("https://test2.com");
|
||||
model.Webhooks[1].Request.Headers.Should().HaveCount(2);
|
||||
model.Webhooks[1].Request.Body.Should().Be("2");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -44,7 +153,7 @@ namespace WireMock.Net.Tests.Serialization
|
||||
// Assign
|
||||
var request = Request.Create();
|
||||
var response = Response.Create().WithBodyAsJson(new { x = "x" }).WithTransformer();
|
||||
var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 42, null, null, null, null);
|
||||
var mapping = new Mapping(Guid.NewGuid(), "", null, _settings, request, response, 42, null, null, null, null, null);
|
||||
|
||||
// Act
|
||||
var model = _sut.ToMappingModel(mapping);
|
||||
|
||||
101
test/WireMock.Net.Tests/Serialization/WebhookMapperTests.cs
Normal file
101
test/WireMock.Net.Tests/Serialization/WebhookMapperTests.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Serialization;
|
||||
using WireMock.Types;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Serialization
|
||||
{
|
||||
public class WebhookMapperTests
|
||||
{
|
||||
[Fact]
|
||||
public void WebhookMapper_Map_Model_BodyAsString_And_UseTransformerIsFalse()
|
||||
{
|
||||
// Assign
|
||||
var model = new WebhookModel
|
||||
{
|
||||
Request = new WebhookRequestModel
|
||||
{
|
||||
Url = "https://localhost",
|
||||
Method = "get",
|
||||
Headers = new Dictionary<string, string>
|
||||
{
|
||||
{ "x", "y" }
|
||||
},
|
||||
Body = "test",
|
||||
UseTransformer = false
|
||||
}
|
||||
};
|
||||
|
||||
var result = WebhookMapper.Map(model);
|
||||
|
||||
result.Request.Url.Should().Be("https://localhost");
|
||||
result.Request.Method.Should().Be("get");
|
||||
result.Request.Headers.Should().HaveCount(1);
|
||||
result.Request.BodyData.BodyAsJson.Should().BeNull();
|
||||
result.Request.BodyData.BodyAsString.Should().Be("test");
|
||||
result.Request.BodyData.DetectedBodyType.Should().Be(BodyType.String);
|
||||
result.Request.UseTransformer.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebhookMapper_Map_Model_BodyAsString_And_UseTransformerIsTrue()
|
||||
{
|
||||
// Assign
|
||||
var model = new WebhookModel
|
||||
{
|
||||
Request = new WebhookRequestModel
|
||||
{
|
||||
Url = "https://localhost",
|
||||
Method = "get",
|
||||
Headers = new Dictionary<string, string>
|
||||
{
|
||||
{ "x", "y" }
|
||||
},
|
||||
Body = "test",
|
||||
UseTransformer = true
|
||||
}
|
||||
};
|
||||
|
||||
var result = WebhookMapper.Map(model);
|
||||
|
||||
result.Request.Url.Should().Be("https://localhost");
|
||||
result.Request.Method.Should().Be("get");
|
||||
result.Request.Headers.Should().HaveCount(1);
|
||||
result.Request.BodyData.BodyAsJson.Should().BeNull();
|
||||
result.Request.BodyData.BodyAsString.Should().Be("test");
|
||||
result.Request.BodyData.DetectedBodyType.Should().Be(BodyType.String);
|
||||
result.Request.UseTransformer.Should().BeTrue();
|
||||
result.Request.TransformerType.Should().Be(TransformerType.Handlebars);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WebhookMapper_Map_Model_BodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var model = new WebhookModel
|
||||
{
|
||||
Request = new WebhookRequestModel
|
||||
{
|
||||
Url = "https://localhost",
|
||||
Method = "get",
|
||||
Headers = new Dictionary<string, string>
|
||||
{
|
||||
{ "x", "y" }
|
||||
},
|
||||
BodyAsJson = new { n = 12345 }
|
||||
}
|
||||
};
|
||||
|
||||
var result = WebhookMapper.Map(model);
|
||||
|
||||
result.Request.Url.Should().Be("https://localhost");
|
||||
result.Request.Method.Should().Be("get");
|
||||
result.Request.Headers.Should().HaveCount(1);
|
||||
result.Request.BodyData.BodyAsString.Should().BeNull();
|
||||
result.Request.BodyData.BodyAsJson.Should().NotBeNull();
|
||||
result.Request.BodyData.DetectedBodyType.Should().Be(BodyType.Json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,29 +33,29 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Codecov" Version="1.10.0" />
|
||||
<PackageReference Include="coverlet.msbuild" Version="3.0.0-preview.9">
|
||||
<PackageReference Include="coverlet.msbuild" Version="3.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="3.0.0-preview.9">
|
||||
<PackageReference Include="coverlet.collector" Version="3.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
||||
<PackageReference Include="Moq" Version="4.13.1" />
|
||||
<PackageReference Include="Moq" Version="4.16.0" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="RestEase" Version="1.4.10" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="NFluent" Version="2.7.0" />
|
||||
<PackageReference Include="NFluent" Version="2.7.1" />
|
||||
<!--<PackageReference Include="OpenCover" Version="4.7.922" />-->
|
||||
<!--<PackageReference Include="ReportGenerator" Version="4.8.1" />-->
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user