Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fcc95ff06f | ||
|
|
020cc15420 | ||
|
|
aeb15725e4 | ||
|
|
a06ee6b158 | ||
|
|
b0076b4e81 | ||
|
|
6c61f87ef3 | ||
|
|
35cd06b47b | ||
|
|
b925c537c7 | ||
|
|
f80925c1fb | ||
|
|
43cff52b69 | ||
|
|
7b93b2668d | ||
|
|
70a9180af4 | ||
|
|
acd6592562 | ||
|
|
2a010dcd42 | ||
|
|
8151119cca | ||
|
|
77000372c6 | ||
|
|
ec248a9a78 | ||
|
|
2f7e3a3178 | ||
|
|
ac9c51e34e | ||
|
|
8ba243ddcd | ||
|
|
d4b95e73ea | ||
|
|
f9ae045847 | ||
|
|
05b5876b5c | ||
|
|
c1bd2d315f | ||
|
|
8917a6eaaa | ||
|
|
3cc9040f51 |
10
.github/workflows/CreateRelease.yml
vendored
@@ -1,5 +1,8 @@
|
||||
name: CreateRelease
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
@@ -10,6 +13,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
generate_release_notes: true
|
||||
6
.github/workflows/ci.yml
vendored
@@ -22,6 +22,9 @@ jobs:
|
||||
- name: 'WireMock.Net.Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Tests.UsingNuGet'
|
||||
run: dotnet test './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests'
|
||||
run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
@@ -46,6 +49,9 @@ jobs:
|
||||
- name: 'WireMock.Net.Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: 'WireMock.Net.Tests.UsingNuGet'
|
||||
run: dotnet test './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj' -c Release
|
||||
|
||||
- name: 'WireMock.Net.TUnitTests'
|
||||
run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
|
||||
33
CHANGELOG.md
@@ -1,3 +1,36 @@
|
||||
# 1.8.15 (18 July 2025)
|
||||
- [#1331](https://github.com/wiremock/WireMock.Net/pull/1331) - Correctly map the Pact Interaction Description property [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1330](https://github.com/wiremock/WireMock.Net/issues/1330) - Generated Pact-compatible consumer contract does not contain description [bug]
|
||||
|
||||
# 1.8.14 (13 July 2025)
|
||||
- [#1325](https://github.com/wiremock/WireMock.Net/pull/1325) - Add method CreateHttpClientFactory [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1326](https://github.com/wiremock/WireMock.Net/pull/1326) - Implement IMimeMessageData [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1329](https://github.com/wiremock/WireMock.Net/pull/1329) - Fix HandlebarsContext.ParseAndEvaluate [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1327](https://github.com/wiremock/WireMock.Net/issues/1327) - Response Body Does Not Evaluate Multiple Handlebars Templates [bug]
|
||||
|
||||
# 1.8.13 (23 June 2025)
|
||||
- [#1322](https://github.com/wiremock/WireMock.Net/pull/1322) - Add Scenario set State method [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1321](https://github.com/wiremock/WireMock.Net/issues/1321) - Feature: Setting individual scenario state via Admin API [feature]
|
||||
|
||||
# 1.8.12 (15 June 2025)
|
||||
- [#1317](https://github.com/wiremock/WireMock.Net/pull/1317) - Set description when converting MappingModel to IRespondWithAProvider [feature] contributed by [BodrickLight](https://github.com/BodrickLight)
|
||||
- [#1320](https://github.com/wiremock/WireMock.Net/pull/1320) - Fix TypeLoader [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1319](https://github.com/wiremock/WireMock.Net/issues/1319) - Why is IRequestMessage.BodyAsMimeMessage null in new versions (> 1.8.7) [bug]
|
||||
|
||||
# 1.8.11 (11 June 2025)
|
||||
- [#1311](https://github.com/wiremock/WireMock.Net/pull/1311) - Bump Testcontainers version to 4.5.0 [feature] contributed by [scrocquesel](https://github.com/scrocquesel)
|
||||
- [#1313](https://github.com/wiremock/WireMock.Net/pull/1313) - Update RandomDataGenerator.Net to 1.0.19 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1315](https://github.com/wiremock/WireMock.Net/pull/1315) - Fix for WithTransformer and JsonBody as list [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1310](https://github.com/wiremock/WireMock.Net/issues/1310) - Binary compat issue with testcontainers 4.5.0 [bug]
|
||||
- [#1312](https://github.com/wiremock/WireMock.Net/issues/1312) - WithTransformer breaks when the response BodyAsJson is a List [bug]
|
||||
|
||||
# 1.8.10 (10 June 2025)
|
||||
- [#1306](https://github.com/wiremock/WireMock.Net/pull/1306) - Update RequestModelBuilder (add WithHeader) [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1308](https://github.com/wiremock/WireMock.Net/pull/1308) - For some projects, change dependency to WireMock.Net.Minimal [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1309](https://github.com/wiremock/WireMock.Net/pull/1309) - Update AwesomeAssertions to version 9 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1305](https://github.com/wiremock/WireMock.Net/issues/1305) - AdminApiMappingBuilder do not expose WithHeader for Request [feature]
|
||||
- [#1307](https://github.com/wiremock/WireMock.Net/issues/1307) - Update WireMock.Net.AwesomeAssertions to use latest version from AwesomeAssertions [feature]
|
||||
|
||||
# 1.8.9 (28 May 2025)
|
||||
- [#1303](https://github.com/wiremock/WireMock.Net/pull/1303) - Add option to provide X509Certificate [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1302](https://github.com/wiremock/WireMock.Net/issues/1302) - Support In-Memory SSL Certificate [feature]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.8.9</VersionPrefix>
|
||||
<VersionPrefix>1.8.15</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=1.8.9
|
||||
SET version=1.8.15
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 1.8.8 (28 May 2025)
|
||||
- #1303 Add option to provide X509Certificate [feature]
|
||||
- #1302 Support In-Memory SSL Certificate [feature]
|
||||
# 1.8.15 (18 July 2025)
|
||||
- #1331 Correctly map the Pact Interaction Description property [bug]
|
||||
- #1330 Generated Pact-compatible consumer contract does not contain description [bug]
|
||||
|
||||
The full release notes can be found here: https://github.com/wiremock/WireMock.Net/blob/master/CHANGELOG.md
|
||||
@@ -1,4 +1,4 @@
|
||||
# WireMock.Net
|
||||
#  WireMock.Net
|
||||
A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) which mimics the functionality from the JAVA based [WireMock](http://wiremock.org).
|
||||
|
||||
For more info, see also this WIKI page: [What is WireMock.Net](https://github.com/wiremock/WireMock.Net/wiki/What-Is-WireMock.Net).
|
||||
@@ -132,3 +132,8 @@ For more details see also [Docker](https://github.com/wiremock/WireMock.Net-dock
|
||||
|
||||
#### HTTPS / SSL
|
||||
More details on using HTTPS (SSL) can be found here [Wiki : HTTPS](https://github.com/wiremock/WireMock.Net/wiki/Using-HTTPS-(SSL))
|
||||
|
||||
---
|
||||
|
||||
## Powered by
|
||||
[](https://jb.gg/OpenSource)
|
||||
|
||||
@@ -38,12 +38,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Client", "examples\WireMock.Net.Client\WireMock.Net.Client.csproj", "{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Proxy.Net452", "examples\WireMock.Net.Console.Proxy.Net452\WireMock.Net.Console.Proxy.Net452.csproj", "{26433A8F-BF01-4962-97EB-81BFFBB61096}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Service", "examples\Wiremock.Net.Service\WireMock.Net.Service.csproj", "{7F0B2446-0363-4720-AF46-F47F83B557DC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Console.Net452.Classic", "examples\WireMock.Net.Console.Net452.Classic\WireMock.Net.Console.Net452.Classic.csproj", "{668F689E-57B4-422E-8846-C0FF643CA268}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Console.RequestLogTest", "examples\WireMock.Net.Console.RequestLogTest\WireMock.Net.Console.RequestLogTest.csproj", "{A9D039B9-7509-4CF1-9EFD-87EB82998575}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.OpenApiParser.ConsoleApp", "examples\WireMock.Net.OpenApiParser.ConsoleApp\WireMock.Net.OpenApiParser.ConsoleApp.csproj", "{5C09FB93-1535-4F92-AF26-21E8A061EE4A}"
|
||||
@@ -136,6 +132,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Shared", "src\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Minimal", "src\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj", "{BFEF8990-65B3-4274-310F-7355F0B84035}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.ConsoleApp.UsingNuGet", "examples\WireMock.Net.ConsoleApp.UsingNuGet\WireMock.Net.ConsoleApp.UsingNuGet.csproj", "{1F80A6E6-D146-4E40-9EA8-49DB8494239F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.Tests.UsingNuGet", "test\WireMock.Net.Tests.UsingNuGet\WireMock.Net.Tests.UsingNuGet.csproj", "{BBA332C6-28A9-42E7-9C4D-A0816E52A198}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -166,18 +166,10 @@ Global
|
||||
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{26433A8F-BF01-4962-97EB-81BFFBB61096}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{668F689E-57B4-422E-8846-C0FF643CA268}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{668F689E-57B4-422E-8846-C0FF643CA268}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -326,6 +318,14 @@ Global
|
||||
{BFEF8990-65B3-4274-310F-7355F0B84035}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BFEF8990-65B3-4274-310F-7355F0B84035}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BFEF8990-65B3-4274-310F-7355F0B84035}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1F80A6E6-D146-4E40-9EA8-49DB8494239F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1F80A6E6-D146-4E40-9EA8-49DB8494239F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1F80A6E6-D146-4E40-9EA8-49DB8494239F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1F80A6E6-D146-4E40-9EA8-49DB8494239F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BBA332C6-28A9-42E7-9C4D-A0816E52A198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BBA332C6-28A9-42E7-9C4D-A0816E52A198}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BBA332C6-28A9-42E7-9C4D-A0816E52A198}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BBA332C6-28A9-42E7-9C4D-A0816E52A198}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -337,9 +337,7 @@ Global
|
||||
{B6269AAC-170A-43D5-8B9A-579DED3D9A95} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{31DC2EF8-C3FE-467D-84BE-FB5D956E612E} = {0BB8B634-407A-4610-A91F-11586990767A}
|
||||
{74D91AD0-D96D-4FD2-AEC5-CC49D38346C0} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{26433A8F-BF01-4962-97EB-81BFFBB61096} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{7F0B2446-0363-4720-AF46-F47F83B557DC} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{668F689E-57B4-422E-8846-C0FF643CA268} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{A9D039B9-7509-4CF1-9EFD-87EB82998575} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{5C09FB93-1535-4F92-AF26-21E8A061EE4A} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{B6269AAC-170A-4346-8B9A-579DED3D9A95} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
@@ -379,6 +377,8 @@ Global
|
||||
{F8B4A93E-46EF-4237-88FE-15FDAB7635D4} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{D3804228-91F4-4502-9595-39584E5A0177} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{BFEF8990-65B3-4274-310F-7355F0B84035} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{1F80A6E6-D146-4E40-9EA8-49DB8494239F} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{BBA332C6-28A9-42E7-9C4D-A0816E52A198} = {0BB8B634-407A-4610-A91F-11586990767A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
@@ -109,6 +109,13 @@ jobs:
|
||||
packageType: 'sdk'
|
||||
version: '8.0.x'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'WireMock.Net.Tests.UsingNuGet'
|
||||
inputs:
|
||||
command: 'test'
|
||||
projects: './test/WireMock.Net.Tests.UsingNuGet/WireMock.Net.Tests.UsingNuGet.csproj'
|
||||
arguments: '--configuration Release'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'WireMock.Net.Tests with Coverage'
|
||||
inputs:
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\WireMock.Net.Console.Net452.Classic\MainApp.cs" Link="MainApp.cs" />
|
||||
<Compile Include="..\WireMock.Net.Console.Net452.Classic\CustomFileSystemFileHandler.cs" Link="CustomFileSystemFileHandler.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="__admin\mappings\*.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="HandlebarsDotNet.Helpers.Core" publicKeyToken="00d131fae0c250bc" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.3.3.0" newVersion="2.3.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Handlebars" publicKeyToken="22225d0bf33cd661" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.1.2.0" newVersion="2.1.2.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,16 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.IO;
|
||||
using log4net.Config;
|
||||
|
||||
namespace WireMock.Net.ConsoleApplication;
|
||||
|
||||
static class Program
|
||||
{
|
||||
static void Main(params string[] args)
|
||||
{
|
||||
XmlConfigurator.Configure(new FileInfo("log4net.config"));
|
||||
|
||||
MainApp.Run();
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("WireMock.Net.Console.Net452.Classic")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("WireMock.Net.Console.Net452.Classic")]
|
||||
[assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("668f689e-57b4-422e-8846-c0ff643ca268")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,123 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{668F689E-57B4-422E-8846-C0FF643CA268}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>WireMock.Net.ConsoleApplication</RootNamespace>
|
||||
<AssemblyName>WireMock.Net.ConsoleApplication</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>..\..\resources\WireMock.Net-Logo.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="AnyOf, Version=0.3.0.0, Culture=neutral, PublicKeyToken=b35e6abbb527c6b1, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\AnyOf.0.3.0\lib\net45\AnyOf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Handlebars, Version=2.1.6.0, Culture=neutral, PublicKeyToken=22225d0bf33cd661, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.2.1.6\lib\net451\Handlebars.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Handlebars.Net.Helpers, Version=2.4.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.2.4.3\lib\net452\Handlebars.Net.Helpers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="HandlebarsDotNet.Helpers.Core, Version=2.4.3.0, Culture=neutral, PublicKeyToken=00d131fae0c250bc, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Handlebars.Net.Helpers.Core.2.4.3\lib\net452\HandlebarsDotNet.Helpers.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="log4net, Version=2.0.17.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\log4net.2.0.17\lib\net45\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Stef.Validation, Version=0.1.1.0, Culture=neutral, PublicKeyToken=8f3400880c321038, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Stef.Validation.0.1.1\lib\net40\Stef.Validation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.XML" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CustomFileSystemFileHandler.cs" />
|
||||
<Compile Include="MainApp.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="log4net.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<Content Include="__admin\mappings\11111110-a633-40e8-a244-5cb80bc0ab66.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="__admin\mappings\873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj">
|
||||
<Project>{b6269aac-170a-4346-8b9a-579ded3d9a94}</Project>
|
||||
<Name>WireMock.Net.Abstractions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj">
|
||||
<Project>{d3804228-91f4-4502-9595-39584e5a01ad}</Project>
|
||||
<Name>WireMock.Net</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="log4net">
|
||||
<Version>2.0.17</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
"Request": {
|
||||
"Path": {
|
||||
"Matchers": [
|
||||
{
|
||||
"Name": "WildcardMatcher",
|
||||
"Pattern": "/static/mapping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"BodyAsJson": { "body": "static mapping" },
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"Guid": "873d495f-940e-4b86-a1f4-4f0fc7be8b8b",
|
||||
"Priority": 4,
|
||||
"Request": {
|
||||
"Path": {},
|
||||
"Methods": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
"Response": {
|
||||
"StatusCode": 200,
|
||||
"BodyDestination": "SameAsSource",
|
||||
"Body": "NO PATH OR URL",
|
||||
"UseTransformer": false,
|
||||
"Headers": {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="System.Configuration.IgnoreSectionHandler" />
|
||||
</configSections>
|
||||
<appSettings>
|
||||
<add key="log4net.Internal.Debug" value="true"/>
|
||||
</appSettings>
|
||||
<log4net>
|
||||
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<conversionPattern value="%date [%thread] %-5level %logger{1} - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
<root>
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="ConsoleAppender" />
|
||||
</root>
|
||||
</log4net>
|
||||
</configuration>
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="AnyOf" version="0.3.0" targetFramework="net452" />
|
||||
<package id="Handlebars.Net" version="2.1.6" targetFramework="net452" />
|
||||
<package id="Handlebars.Net.Helpers" version="2.4.3" targetFramework="net452" />
|
||||
<package id="Handlebars.Net.Helpers.Core" version="2.4.3" targetFramework="net452" />
|
||||
<package id="log4net" version="2.0.17" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" />
|
||||
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net452" />
|
||||
<package id="Stef.Validation" version="0.1.1" targetFramework="net452" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -1,60 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.Net.Http;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Net.Console.Proxy.Net452
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string[] urls = { "http://localhost:9091/", "https://localhost:9443/" };
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
Urls = urls,
|
||||
StartAdminInterface = true,
|
||||
ReadStaticMappings = false,
|
||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||
{
|
||||
Url = "http://postman-echo.com/post",
|
||||
//ClientX509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
|
||||
SaveMapping = true,
|
||||
SaveMappingToFile = false,
|
||||
ExcludedHeaders = new[] { "dnt", "Content-Length" }
|
||||
}
|
||||
});
|
||||
|
||||
System.Console.WriteLine("Subscribing to LogEntriesChanged");
|
||||
server.LogEntriesChanged += Server_LogEntriesChanged;
|
||||
|
||||
var uri = new Uri(urls[0]);
|
||||
var form = new MultipartFormDataContent
|
||||
{
|
||||
{ new StringContent("data"), "test", "test.txt" }
|
||||
};
|
||||
new HttpClient().PostAsync(uri, form).GetAwaiter().GetResult();
|
||||
|
||||
System.Console.WriteLine("Unsubscribing to LogEntriesChanged");
|
||||
server.LogEntriesChanged -= Server_LogEntriesChanged;
|
||||
|
||||
form = new MultipartFormDataContent
|
||||
{
|
||||
{ new StringContent("data2"), "test2", "test2.txt" }
|
||||
};
|
||||
new HttpClient().PostAsync(uri, form).GetAwaiter().GetResult();
|
||||
|
||||
System.Console.WriteLine("Press any key to stop the server");
|
||||
System.Console.ReadKey();
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
private static void Server_LogEntriesChanged(object sender, NotifyCollectionChangedEventArgs eventRecordArgs)
|
||||
{
|
||||
System.Console.WriteLine("Server_LogEntriesChanged : {0}", eventRecordArgs.NewItems.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("WireMock.Net.Console.Proxy.Net452")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("WireMock.Net.Console.Proxy.Net452")]
|
||||
[assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("26433a8f-bf01-4962-97eb-81bffbb61096")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{26433A8F-BF01-4962-97EB-81BFFBB61096}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>WireMock.Net.Console.Proxy.Net452</RootNamespace>
|
||||
<AssemblyName>WireMock.Net.Console.Proxy.Net452</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<StartupObject>WireMock.Net.Console.Proxy.Net452.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Condition="'$(Platform)' == 'x64'" Include="..\packages\Libuv.1.10.0\runtimes\win7-x64\native\libuv.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Visible>False</Visible>
|
||||
<Link>libuv.dll</Link>
|
||||
</None>
|
||||
<None Condition="'$(Platform)' == 'x86'" Include="..\packages\Libuv.1.10.0\runtimes\win7-x86\native\libuv.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<Visible>False</Visible>
|
||||
<Link>libuv.dll</Link>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj">
|
||||
<Project>{d3804228-91f4-4502-9595-39584e5a01ad}</Project>
|
||||
<Name>WireMock.Net</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Owin.Host.HttpListener" version="3.1.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net452" />
|
||||
</packages>
|
||||
88
examples/WireMock.Net.ConsoleApp.UsingNuGet/Program.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
|
||||
Directory.SetCurrentDirectory(Path.GetTempPath());
|
||||
|
||||
using var server = WireMockServer.Start();
|
||||
|
||||
var textPlainContent = "This is some plain text";
|
||||
var textPlainContentType = "text/plain";
|
||||
var textPlainContentTypeMatcher = new ContentTypeMatcher(textPlainContentType);
|
||||
var textPlainContentMatcher = new ExactMatcher(textPlainContent);
|
||||
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
|
||||
|
||||
var textJson = "{ \"Key\" : \"Value\" }";
|
||||
var textJsonContentType = "text/json";
|
||||
var textJsonContentTypeMatcher = new ContentTypeMatcher(textJsonContentType);
|
||||
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
|
||||
var jsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
|
||||
|
||||
var imagePngBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC");
|
||||
var imagePngContentMatcher = new ExactObjectMatcher(imagePngBytes);
|
||||
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, null, null, null, imagePngContentMatcher);
|
||||
|
||||
var matchers = new IMatcher[]
|
||||
{
|
||||
textPlainMatcher,
|
||||
jsonMatcher,
|
||||
imagePngMatcher
|
||||
};
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/multipart")
|
||||
.WithMultiPart(matchers)
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBodyAsJson(new
|
||||
{
|
||||
Method = "{{request.Method}}",
|
||||
BodyAsMimeMessage = "{{request.BodyAsMimeMessage.TextBody}}"
|
||||
})
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/multipart2")
|
||||
.WithMultiPart(matchers)
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(request =>
|
||||
{
|
||||
if (request.BodyAsMimeMessage == null)
|
||||
{
|
||||
throw new InvalidProgramException("Not expected");
|
||||
}
|
||||
return "OK";
|
||||
})
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
var formDataContent = new MultipartFormDataContent
|
||||
{
|
||||
{ new StringContent(textPlainContent, Encoding.UTF8, textPlainContentType), "text" },
|
||||
{ new StringContent(textJson, Encoding.UTF8, textJsonContentType), "json" }
|
||||
};
|
||||
|
||||
var fileContent = new ByteArrayContent(imagePngBytes);
|
||||
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
|
||||
formDataContent.Add(fileContent, "somefile", "image.png");
|
||||
|
||||
var client = server.CreateClient();
|
||||
|
||||
var response = await client.PostAsync("/multipart", formDataContent);
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
Console.WriteLine(content);
|
||||
|
||||
var response2 = await client.PostAsync("/multipart2", formDataContent);
|
||||
var content2 = await response2.Content.ReadAsStringAsync();
|
||||
Console.WriteLine(content2);
|
||||
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="SonarAnalyzer.CSharp" Version="10.12.0.118525" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--<ItemGroup>
|
||||
<PackageReference Include="WireMock.Net" Version="1.8.11" />
|
||||
</ItemGroup>-->
|
||||
|
||||
</Project>
|
||||
@@ -113,20 +113,13 @@
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj">
|
||||
<Project>{b6269aac-170a-4346-8b9a-579ded3d9a94}</Project>
|
||||
<Name>WireMock.Net.Abstractions</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj">
|
||||
<Project>{d3804228-91f4-4502-9595-39584e5a01ad}</Project>
|
||||
<Name>WireMock.Net</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="log4net">
|
||||
<Version>3.0.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="WireMock.Net">
|
||||
<Version>1.8.11</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -159,9 +159,7 @@ internal class Program
|
||||
private static async Task TestWindowsCopyAsync()
|
||||
{
|
||||
var builder = new WireMockContainerBuilder()
|
||||
.WithWatchStaticMappings(true)
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true);
|
||||
.WithWatchStaticMappings(true);
|
||||
|
||||
var container = builder.Build();
|
||||
|
||||
@@ -186,8 +184,6 @@ internal class Program
|
||||
var mappings = await adminClient.GetMappingsAsync();
|
||||
Console.WriteLine("mappings = " + JsonConvert.SerializeObject(mappings, Formatting.Indented));
|
||||
|
||||
await Task.Delay(1_000);
|
||||
|
||||
await container.StopAsync();
|
||||
}
|
||||
|
||||
@@ -205,9 +201,7 @@ internal class Program
|
||||
.WithNetwork(dummyNetwork)
|
||||
.WithAdminUserNameAndPassword("x", "y")
|
||||
.WithMappings(mappingsPath)
|
||||
.WithWatchStaticMappings(true)
|
||||
// .WithAutoRemove(true)
|
||||
.WithCleanUp(true);
|
||||
.WithWatchStaticMappings(true);
|
||||
|
||||
if (image != null)
|
||||
{
|
||||
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 12 KiB |
BIN
resources/logo_32x32.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,15 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Admin.Scenarios;
|
||||
|
||||
/// <summary>
|
||||
/// ScenarioStateModel
|
||||
/// </summary>
|
||||
[FluentBuilder.AutoGenerateBuilder]
|
||||
public class ScenarioStateUpdateModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the NextState.
|
||||
/// </summary>
|
||||
public string? State { get; set; }
|
||||
}
|
||||
@@ -138,4 +138,27 @@ public partial class RequestModelBuilder
|
||||
return builder.Build();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WithHeader: matching based on name, pattern and matchBehaviour.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="rejectOnMatch">The match behaviour. Default value is <c>false</c>.</param>
|
||||
/// <returns>The <see cref="RequestModelBuilder"/>.</returns>
|
||||
public RequestModelBuilder WithHeader(string name, string pattern, bool rejectOnMatch = false)
|
||||
{
|
||||
return WithHeaders(headersBuilder => headersBuilder
|
||||
.Add(headerBuilder => headerBuilder
|
||||
.WithName(name)
|
||||
.WithMatchers(matchersBuilder => matchersBuilder
|
||||
.Add(matcherBuilder => matcherBuilder
|
||||
.WithName("WildcardMatcher")
|
||||
.WithPattern(pattern)
|
||||
.WithRejectOnMatch(rejectOnMatch)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,7 @@ public interface IRequestMessage
|
||||
/// The original body as MimeMessage.
|
||||
/// Convenience getter for Handlebars and WireMockAssertions.
|
||||
/// </summary>
|
||||
object? BodyAsMimeMessage { get; }
|
||||
Models.Mime.IMimeMessageData? BodyAsMimeMessage { get; }
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Models.Mime;
|
||||
|
||||
/// <summary>
|
||||
/// An interface exposing the public, readable properties of a ContentDisposition.
|
||||
/// </summary>
|
||||
public interface IContentDispositionData
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the disposition.
|
||||
/// </summary>
|
||||
/// <value>The disposition.</value>
|
||||
string Disposition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a value indicating whether the <see cref="IMimeEntityData"/> is an attachment.
|
||||
/// </summary>
|
||||
/// <value><see langword="true" /> if the <see cref="IMimeEntityData"/> is an attachment; otherwise, <see langword="false" />.</value>
|
||||
bool IsAttachment { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of parameters on the ContentDisposition.
|
||||
/// </summary>
|
||||
/// <value>The parameters.</value>
|
||||
public IList<string> Parameters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the name of the file.
|
||||
/// </summary>
|
||||
/// <value>The name of the file.</value>
|
||||
string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the creation-date parameter.
|
||||
/// </summary>
|
||||
/// <value>The creation date.</value>
|
||||
DateTimeOffset? CreationDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the modification-date parameter.
|
||||
/// </summary>
|
||||
/// <value>The modification date.</value>
|
||||
DateTimeOffset? ModificationDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the read-date parameter.
|
||||
/// </summary>
|
||||
/// <value>The read date.</value>
|
||||
DateTimeOffset? ReadDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the size parameter.
|
||||
/// </summary>
|
||||
/// <value>The size.</value>
|
||||
long? Size { get; }
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace WireMock.Models.Mime;
|
||||
|
||||
/// <summary>
|
||||
/// An interface exposing the public, readable properties of a ContentType
|
||||
/// with complex types simplified to a generic object.
|
||||
/// </summary>
|
||||
public interface IContentTypeData
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the type of the media.
|
||||
/// </summary>
|
||||
/// <value>The type of the media.</value>
|
||||
string MediaType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the media subtype.
|
||||
/// </summary>
|
||||
/// <value>The media subtype.</value>
|
||||
string MediaSubtype { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of parameters on the ContentType.
|
||||
/// </summary>
|
||||
/// <value>The parameters.</value>
|
||||
IList<string> Parameters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the boundary parameter.
|
||||
/// </summary>
|
||||
/// <value>The boundary.</value>
|
||||
string Boundary { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the charset parameter.
|
||||
/// </summary>
|
||||
/// <value>The charset.</value>
|
||||
string Charset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the charset parameter as an Encoding.
|
||||
/// </summary>
|
||||
/// <value>The charset encoding.</value>
|
||||
Encoding CharsetEncoding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the format parameter.
|
||||
/// </summary>
|
||||
/// <value>The format.</value>
|
||||
string Format { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the simple mime-type.
|
||||
/// </summary>
|
||||
/// <value>The mime-type.</value>
|
||||
string MimeType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the name parameter.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
string Name { get; }
|
||||
}
|
||||
54
src/WireMock.Net.Abstractions/Models/Mime/IMimeEntityData.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Models.Mime;
|
||||
|
||||
/// <summary>
|
||||
/// A simplified interface exposing the public, readable properties of MimeEntity.
|
||||
/// </summary>
|
||||
public interface IMimeEntityData
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the list of headers.
|
||||
/// </summary>
|
||||
/// <value>The list of headers.</value>
|
||||
IList<string> Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the content disposition.
|
||||
/// </summary>
|
||||
/// <value>The content disposition.</value>
|
||||
IContentDispositionData? ContentDisposition { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the type of the content.
|
||||
/// </summary>
|
||||
/// <value>The type of the content.</value>
|
||||
IContentTypeData? ContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the base content URI.
|
||||
/// </summary>
|
||||
/// <value>The base content URI or <see langword="null"/>.</value>
|
||||
Uri ContentBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the content location.
|
||||
/// </summary>
|
||||
/// <value>The content location or <see langword="null"/>.</value>
|
||||
Uri ContentLocation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the Content-Id.
|
||||
/// </summary>
|
||||
/// <value>The content identifier.</value>
|
||||
string ContentId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a value indicating whether this <see cref="IMimeEntityData"/> is an attachment.
|
||||
/// </summary>
|
||||
/// <value><see langword="true" /> if this <see cref="IMimeEntityData"/> is an attachment; otherwise, <see langword="false" />.</value>
|
||||
bool IsAttachment { get; }
|
||||
}
|
||||
186
src/WireMock.Net.Abstractions/Models/Mime/IMimeMessageData.cs
Normal file
@@ -0,0 +1,186 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WireMock.Models.Mime;
|
||||
|
||||
/// <summary>
|
||||
/// A simplified interface exposing the public, readable properties of a MIME message.
|
||||
/// </summary>
|
||||
public interface IMimeMessageData
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the list of headers.
|
||||
/// </summary>
|
||||
/// <value>The list of headers.</value>
|
||||
IList<string> Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of the Importance header.
|
||||
/// </summary>
|
||||
/// <value>The importance, as an integer.</value>
|
||||
int Importance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of the Priority header.
|
||||
/// </summary>
|
||||
/// <value>The priority, as an integer.</value>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of the X-Priority header.
|
||||
/// </summary>
|
||||
/// <value>The X-priority, as an integer.</value>
|
||||
int XPriority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the address in the Sender header.
|
||||
/// </summary>
|
||||
/// <value>The address in the Sender header.</value>
|
||||
string Sender { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the address in the Resent-Sender header.
|
||||
/// </summary>
|
||||
/// <value>The address in the Resent-Sender header.</value>
|
||||
string ResentSender { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the From header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the From header.</value>
|
||||
IList<string> From { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Resent-From header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Resent-From header.</value>
|
||||
IList<string> ResentFrom { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Reply-To header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Reply-To header.</value>
|
||||
IList<string> ReplyTo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Resent-Reply-To header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Resent-Reply-To header.</value>
|
||||
IList<string> ResentReplyTo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the To header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the To header.</value>
|
||||
IList<string> To { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Resent-To header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Resent-To header.</value>
|
||||
IList<string> ResentTo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Cc header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Cc header.</value>
|
||||
IList<string> Cc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Resent-Cc header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Resent-Cc header.</value>
|
||||
IList<string> ResentCc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Bcc header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Bcc header.</value>
|
||||
IList<string> Bcc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of addresses in the Resent-Bcc header.
|
||||
/// </summary>
|
||||
/// <value>The list of addresses in the Resent-Bcc header.</value>
|
||||
IList<string> ResentBcc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the subject of the message.
|
||||
/// </summary>
|
||||
/// <value>The subject of the message.</value>
|
||||
string Subject { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the date of the message.
|
||||
/// </summary>
|
||||
/// <value>The date of the message.</value>
|
||||
DateTimeOffset Date { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the Resent-Date of the message.
|
||||
/// </summary>
|
||||
/// <value>The Resent-Date of the message.</value>
|
||||
DateTimeOffset ResentDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the list of references to other messages.
|
||||
/// </summary>
|
||||
/// <value>The references.</value>
|
||||
IList<string> References { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the Message-Id that this message is replying to.
|
||||
/// </summary>
|
||||
/// <value>The message id that this message is in reply to.</value>
|
||||
string InReplyTo { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the message identifier.
|
||||
/// </summary>
|
||||
/// <value>The message identifier.</value>
|
||||
string MessageId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the Resent-Message-Id header.
|
||||
/// </summary>
|
||||
/// <value>The Resent-Message-Id.</value>
|
||||
string ResentMessageId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the MIME-Version.
|
||||
/// </summary>
|
||||
/// <value>The MIME version.</value>
|
||||
Version MimeVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the body of the message.
|
||||
/// </summary>
|
||||
/// <value>The body of the message.</value>
|
||||
IMimeEntityData Body { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the text body of the message if it exists.
|
||||
/// </summary>
|
||||
/// <value>The text body if it exists; otherwise, <see langword="null"/>.</value>
|
||||
string TextBody { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the html body of the message if it exists.
|
||||
/// </summary>
|
||||
/// <value>The html body if it exists; otherwise, <see langword="null"/>.</value>
|
||||
string HtmlBody { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the body parts of the message.
|
||||
/// </summary>
|
||||
/// <value>The body parts.</value>
|
||||
IList<IMimePartData> BodyParts { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the attachments.
|
||||
/// </summary>
|
||||
/// <value>The attachments.</value>
|
||||
IList<IMimeEntityData> Attachments { get; }
|
||||
}
|
||||
57
src/WireMock.Net.Abstractions/Models/Mime/IMimePartData.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace WireMock.Models.Mime;
|
||||
|
||||
/// <summary>
|
||||
/// A simplified interface exposing the public, readable properties of MimePart.
|
||||
/// </summary>
|
||||
public interface IMimePartData : IMimeEntityData
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the description of the content if available.
|
||||
/// </summary>
|
||||
/// <value>The description of the content.</value>
|
||||
string ContentDescription { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the duration of the content if available.
|
||||
/// </summary>
|
||||
/// <value>The duration of the content.</value>
|
||||
int? ContentDuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the md5sum of the content.
|
||||
/// </summary>
|
||||
/// <value>The md5sum of the content.</value>
|
||||
string ContentMd5 { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the content transfer encoding.
|
||||
/// </summary>
|
||||
/// <value>The content transfer encoding as a string.</value>
|
||||
string ContentTransferEncoding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the name of the file.
|
||||
/// </summary>
|
||||
/// <value>The name of the file.</value>
|
||||
string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the MIME content.
|
||||
/// </summary>
|
||||
/// <value>The MIME content.</value>
|
||||
IDictionary<string, object?> Content { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Open the decoded content stream.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Provides a means of reading the decoded content without having to first write it to another stream.
|
||||
/// </remarks>
|
||||
/// <returns>The decoded content stream.</returns>
|
||||
Stream Open();
|
||||
}
|
||||
@@ -161,6 +161,11 @@ public interface IWireMockServer : IDisposable
|
||||
/// </summary>
|
||||
bool ResetScenario(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Sets a scenario to a state.
|
||||
/// </summary>
|
||||
bool SetScenarioState(string name, string? state);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the LogEntries.
|
||||
/// </summary>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using FluentAssertions.Primitives;
|
||||
using AwesomeAssertions.Primitives;
|
||||
using WireMock.Server;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
global using System.Linq;
|
||||
global using FluentAssertions;
|
||||
global using FluentAssertions.Execution;
|
||||
global using AwesomeAssertions;
|
||||
global using AwesomeAssertions.Execution;
|
||||
@@ -32,11 +32,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AwesomeAssertions" Version="8.1.0" />
|
||||
<PackageReference Include="AwesomeAssertions" Version="9.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -40,7 +40,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -34,7 +34,7 @@
|
||||
<Target Name="CheckIfShouldKillVBCSCompiler" />
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net\WireMock.Net.csproj" />
|
||||
<ProjectReference Include="..\WireMock.Net.Minimal\WireMock.Net.Minimal.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' or '$(TargetFramework)' == 'net452' ">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using MimeKit;
|
||||
using WireMock.Matchers.Helpers;
|
||||
using WireMock.Models.Mime;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
@@ -12,7 +12,7 @@ namespace WireMock.Matchers;
|
||||
/// </summary>
|
||||
public class MimePartMatcher : IMimePartMatcher
|
||||
{
|
||||
private readonly Func<MimePart, MatchResult>[] _funcs;
|
||||
private readonly Func<IMimePartData, MatchResult>[] _funcs;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Name => nameof(MimePartMatcher);
|
||||
@@ -52,21 +52,21 @@ public class MimePartMatcher : IMimePartMatcher
|
||||
_funcs =
|
||||
[
|
||||
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
|
||||
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
|
||||
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect,
|
||||
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition?.ToString()?.Replace("Content-Disposition: ", string.Empty)) ?? MatchScores.Perfect,
|
||||
mp => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToLowerInvariant()) ?? MatchScores.Perfect,
|
||||
MatchOnContent
|
||||
];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchResult IsMatch(object value)
|
||||
public MatchResult IsMatch(IMimePartData value)
|
||||
{
|
||||
var score = MatchScores.Mismatch;
|
||||
Exception? exception = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (value is MimePart mimePart && Array.TrueForAll(_funcs, func => func(mimePart).IsPerfect()))
|
||||
if (Array.TrueForAll(_funcs, func => func(value).IsPerfect()))
|
||||
{
|
||||
score = MatchScores.Perfect;
|
||||
}
|
||||
@@ -85,7 +85,7 @@ public class MimePartMatcher : IMimePartMatcher
|
||||
return "NotImplemented";
|
||||
}
|
||||
|
||||
private MatchResult MatchOnContent(MimePart mimePart)
|
||||
private MatchResult MatchOnContent(IMimePartData mimePart)
|
||||
{
|
||||
if (ContentMatcher == null)
|
||||
{
|
||||
@@ -94,10 +94,10 @@ public class MimePartMatcher : IMimePartMatcher
|
||||
|
||||
var bodyParserSettings = new BodyParserSettings
|
||||
{
|
||||
Stream = mimePart.Content.Open(),
|
||||
Stream = mimePart.Open(),
|
||||
ContentType = GetContentTypeAsString(mimePart.ContentType),
|
||||
DeserializeJson = true,
|
||||
ContentEncoding = null, // mimePart.ContentType.CharsetEncoding.ToString(),
|
||||
ContentEncoding = null, // mimePart.ContentType?.CharsetEncoding.ToString(),
|
||||
DecompressGZipAndDeflate = true
|
||||
};
|
||||
|
||||
@@ -105,8 +105,8 @@ public class MimePartMatcher : IMimePartMatcher
|
||||
return BodyDataMatchScoreCalculator.CalculateMatchScore(bodyData, ContentMatcher);
|
||||
}
|
||||
|
||||
private static string? GetContentTypeAsString(ContentType? contentType)
|
||||
private static string? GetContentTypeAsString(IContentTypeData? contentType)
|
||||
{
|
||||
return contentType?.ToString().Replace("Content-Type: ", string.Empty);
|
||||
return contentType?.ToString()?.Replace("Content-Type: ", string.Empty);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper class that implements the IContentDispositionData interface
|
||||
/// by wrapping a ContentDisposition object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class provides a simplified, read-only view of a ContentDisposition.
|
||||
/// </remarks>
|
||||
public class ContentDispositionDataWrapper : IContentDispositionData
|
||||
{
|
||||
private readonly ContentDisposition _contentDisposition;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentDispositionDataWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contentDisposition">The ContentDisposition to wrap.</param>
|
||||
public ContentDispositionDataWrapper(ContentDisposition contentDisposition)
|
||||
{
|
||||
_contentDisposition = Guard.NotNull(contentDisposition);
|
||||
|
||||
Parameters = _contentDisposition.Parameters.Select(p => p.ToString()).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Disposition => _contentDisposition.Disposition;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsAttachment => _contentDisposition.IsAttachment;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> Parameters { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string FileName => _contentDisposition.FileName;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset? CreationDate => _contentDisposition.CreationDate;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset? ModificationDate => _contentDisposition.ModificationDate;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset? ReadDate => _contentDisposition.ReadDate;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long? Size => _contentDisposition.Size;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return _contentDisposition.ToString();
|
||||
}
|
||||
}
|
||||
65
src/WireMock.Net.MimePart/Models/ContentTypeDataWrapper.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper class that implements the <see cref="IContentTypeData"/> interface by wrapping a <see cref="ContentType"/> object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class provides a simplified, read-only view of a <see cref="ContentType"/>.
|
||||
/// </remarks>
|
||||
public class ContentTypeDataWrapper : IContentTypeData
|
||||
{
|
||||
private readonly ContentType _contentType;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ContentTypeDataWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contentType">The ContentType to wrap.</param>
|
||||
public ContentTypeDataWrapper(ContentType contentType)
|
||||
{
|
||||
_contentType = Guard.NotNull(contentType);
|
||||
|
||||
Parameters = _contentType.Parameters.Select(p => p.ToString()).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string MediaType => _contentType.MediaType;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string MediaSubtype => _contentType.MediaSubtype;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> Parameters { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Boundary => _contentType.Boundary;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Charset => _contentType.Charset;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Encoding CharsetEncoding => _contentType.CharsetEncoding;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Format => _contentType.Format;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string MimeType => _contentType.MimeType;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Name => _contentType.Name;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return _contentType.ToString();
|
||||
}
|
||||
}
|
||||
61
src/WireMock.Net.MimePart/Models/MimeEntityDataWrapper.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper class that implements the <see cref="IMimeEntityData" /> interface by wrapping an <see cref="IMimeEntity" /> interface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class provides a simplified, read-only view of an <see cref="IMimeEntity"/>.
|
||||
/// </remarks>
|
||||
public class MimeEntityDataWrapper : IMimeEntityData
|
||||
{
|
||||
private readonly IMimeEntity _entity;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MimeEntityDataWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="entity">The MIME entity to wrap.</param>
|
||||
public MimeEntityDataWrapper(IMimeEntity entity)
|
||||
{
|
||||
_entity = Guard.NotNull(entity);
|
||||
|
||||
ContentDisposition = _entity.ContentDisposition != null ? new ContentDispositionDataWrapper(_entity.ContentDisposition) : null;
|
||||
ContentType = _entity.ContentType != null ? new ContentTypeDataWrapper(_entity.ContentType) : null;
|
||||
Headers = _entity.Headers.Select(h => h.ToString()).ToList();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> Headers { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IContentDispositionData? ContentDisposition { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IContentTypeData? ContentType { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Uri ContentBase => _entity.ContentBase;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Uri ContentLocation => _entity.ContentLocation;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ContentId => _entity.ContentId;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsAttachment => _entity.IsAttachment;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return _entity.ToString()!;
|
||||
}
|
||||
}
|
||||
140
src/WireMock.Net.MimePart/Models/MimeMessageDataWrapper.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper class that implements the <see cref="IMimeMessageData" /> interface by wrapping an <see cref="IMimeMessage" /> interface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class provides a simplified, read-only view of an <see cref="IMimeMessage"/>.
|
||||
/// </remarks>
|
||||
internal class MimeMessageDataWrapper : IMimeMessageData
|
||||
{
|
||||
private readonly IMimeMessage _message;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MimeMessageDataWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">The MIME message to wrap.</param>
|
||||
public MimeMessageDataWrapper(IMimeMessage message)
|
||||
{
|
||||
_message = Guard.NotNull(message);
|
||||
|
||||
Bcc = _message.Bcc.Select(h => h.ToString()).ToList();
|
||||
Cc = _message.Cc.Select(h => h.ToString()).ToList();
|
||||
From = _message.From.Select(h => h.ToString()).ToList();
|
||||
Headers = _message.Headers.Select(h => h.ToString()).ToList();
|
||||
References = _message.References.ToList();
|
||||
ReplyTo = _message.ReplyTo.Select(h => h.ToString()).ToList();
|
||||
ResentBcc = _message.ResentBcc.Select(h => h.ToString()).ToList();
|
||||
ResentCc = _message.ResentCc.Select(h => h.ToString()).ToList();
|
||||
ResentFrom = _message.ResentFrom.Select(h => h.ToString()).ToList();
|
||||
ResentReplyTo = _message.ResentReplyTo.Select(h => h.ToString()).ToList();
|
||||
ResentTo = _message.ResentTo.Select(h => h.ToString()).ToList();
|
||||
To = _message.To.Select(h => h.ToString()).ToList();
|
||||
|
||||
Body = new MimeEntityDataWrapper(_message.Body);
|
||||
BodyParts = _message.BodyParts.OfType<MimePart>().Select(mp => new MimePartDataWrapper(mp)).ToList<IMimePartData>();
|
||||
Attachments = _message.Attachments.Select(me => new MimeEntityDataWrapper(me)).ToList<IMimeEntityData>();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> Headers { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Importance => (int)_message.Importance;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int Priority => (int)_message.Priority;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int XPriority => (int)_message.XPriority;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Sender => _message.Sender.Address;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ResentSender => _message.ResentSender.ToString();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> From { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> ResentFrom { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> ReplyTo { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> ResentReplyTo { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> To { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> ResentTo { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> Cc { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> ResentCc { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> Bcc { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> ResentBcc { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Subject => _message.Subject;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset Date => _message.Date;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTimeOffset ResentDate => _message.ResentDate;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<string> References { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string InReplyTo => _message.InReplyTo;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string MessageId => _message.MessageId;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ResentMessageId => _message.ResentMessageId;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Version MimeVersion => _message.MimeVersion;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IMimeEntityData Body { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string TextBody => _message.TextBody;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string HtmlBody => _message.HtmlBody;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<IMimePartData> BodyParts { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IList<IMimeEntityData> Attachments { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return _message.ToString();
|
||||
}
|
||||
}
|
||||
64
src/WireMock.Net.MimePart/Models/MimePartDataWrapper.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Models;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper class that implements the <see cref="IMimePartData" /> interface by wrapping an <see cref="IMimePart"/> interface.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class provides a simplified, read-only view of an <see cref="IMimePart"/>.
|
||||
/// </remarks>
|
||||
public class MimePartDataWrapper : MimeEntityDataWrapper, IMimePartData
|
||||
{
|
||||
private readonly IMimePart _part;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MimePartDataWrapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="part">The MIME part to wrap.</param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// <paramref name="part"/> is <see langword="null"/>.
|
||||
/// </exception>
|
||||
public MimePartDataWrapper(IMimePart part) : base(part)
|
||||
{
|
||||
_part = Guard.NotNull(part);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ContentDescription => _part.ContentDescription;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int? ContentDuration => _part.ContentDuration;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ContentMd5 => _part.ContentMd5;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string ContentTransferEncoding => _part.ContentTransferEncoding.ToString();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string FileName => _part.FileName;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDictionary<string, object?> Content => new Dictionary<string, object?>()
|
||||
{
|
||||
{ nameof(MimePart.Content.Encoding), _part.Content.Encoding },
|
||||
{ nameof(MimePart.Content.NewLineFormat), _part.Content.NewLineFormat },
|
||||
{ nameof(MimePart.Content.Stream), _part.Content.Stream }
|
||||
};
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Stream Open() => _part.Content.Open();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return _part.ToString()!;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ using System.Text;
|
||||
using MimeKit;
|
||||
using Stef.Validation;
|
||||
using WireMock.Http;
|
||||
using WireMock.Models;
|
||||
using WireMock.Models.Mime;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Util;
|
||||
@@ -16,19 +18,19 @@ namespace WireMock.Util;
|
||||
internal class MimeKitUtils : IMimeKitUtils
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public object LoadFromStream(Stream stream)
|
||||
public IMimeMessageData LoadFromStream(Stream stream)
|
||||
{
|
||||
return MimeMessage.Load(Guard.NotNull(stream));
|
||||
return new MimeMessageDataWrapper(MimeMessage.Load(Guard.NotNull(stream)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryGetMimeMessage(IRequestMessage requestMessage, [NotNullWhen(true)] out object? mimeMessage)
|
||||
public bool TryGetMimeMessage(IRequestMessage requestMessage, [NotNullWhen(true)] out IMimeMessageData? mimeMessageData)
|
||||
{
|
||||
Guard.NotNull(requestMessage);
|
||||
|
||||
if (requestMessage.BodyData != null &&
|
||||
requestMessage.Headers?.TryGetValue(HttpKnownHeaderNames.ContentType, out var contentTypeHeader) == true &&
|
||||
StartsWithMultiPart(contentTypeHeader) // Only parse when "multipart/mixed"
|
||||
StartsWithMultiPart(contentTypeHeader)
|
||||
)
|
||||
{
|
||||
var bytes = requestMessage.BodyData?.DetectedBodyType switch
|
||||
@@ -44,26 +46,14 @@ internal class MimeKitUtils : IMimeKitUtils
|
||||
|
||||
var fixedBytes = FixBytes(bytes, contentTypeHeader[0]);
|
||||
|
||||
mimeMessage = LoadFromStream(new MemoryStream(fixedBytes));
|
||||
mimeMessageData = LoadFromStream(new MemoryStream(fixedBytes));
|
||||
return true;
|
||||
}
|
||||
|
||||
mimeMessage = null;
|
||||
mimeMessageData = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<object> GetBodyParts(object mimeMessage)
|
||||
{
|
||||
if (mimeMessage is not MimeMessage mm)
|
||||
{
|
||||
throw new ArgumentException($"The mimeMessage must be of type {nameof(MimeMessage)}", nameof(mimeMessage));
|
||||
}
|
||||
|
||||
return mm.BodyParts
|
||||
.OfType<MimePart>()
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private static bool StartsWithMultiPart(WireMockList<string> contentTypeHeader)
|
||||
{
|
||||
|
||||
@@ -36,9 +36,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="PolySharp" Version="1.15.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PackageReference Include="Nullable" Version="1.3.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
18
src/WireMock.Net.Minimal/Http/WireMockHttpClientFactory.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright © WireMock.Net
|
||||
#if NET5_0_OR_GREATER
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using WireMock.Server;
|
||||
|
||||
namespace WireMock.Http;
|
||||
|
||||
internal class WireMockHttpClientFactory(WireMockServer server, params DelegatingHandler[] handlers) : IHttpClientFactory
|
||||
{
|
||||
private readonly Lazy<HttpClient> _lazyHttpClient = new(() => server.CreateClient());
|
||||
|
||||
public HttpClient CreateClient(string name)
|
||||
{
|
||||
return handlers.Length > 0 ? server.CreateClient(handlers) : _lazyHttpClient.Value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -86,7 +86,7 @@ public interface IMapping
|
||||
WireMockServerSettings Settings { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is State started ?
|
||||
/// Indicates if the state is started or manually set to a value.
|
||||
/// </summary>
|
||||
bool IsStartState { get; }
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ public class RequestMessageMultiPartMatcher : IRequestMatcher
|
||||
foreach (var mimePartMatcher in Matchers.OfType<IMimePartMatcher>().ToArray())
|
||||
{
|
||||
score = MatchScores.Mismatch;
|
||||
foreach (var mimeBodyPart in MimeKitUtils.GetBodyParts(message))
|
||||
|
||||
foreach (var mimeBodyPart in message.BodyParts)
|
||||
{
|
||||
var matchResult = mimePartMatcher.IsMatch(mimeBodyPart);
|
||||
if (matchResult.IsPerfect())
|
||||
|
||||
@@ -85,7 +85,7 @@ public class RequestMessage : IRequestMessage
|
||||
#if MIMEKIT
|
||||
/// <inheritdoc />
|
||||
[Newtonsoft.Json.JsonIgnore] // Issue 1001
|
||||
public object? BodyAsMimeMessage { get; }
|
||||
public Models.Mime.IMimeMessageData? BodyAsMimeMessage { get; }
|
||||
#endif
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -42,8 +42,7 @@ internal static class PactMapper
|
||||
|
||||
var interaction = new Interaction
|
||||
{
|
||||
Description = mapping.Description,
|
||||
ProviderState = mapping.Title,
|
||||
Description = !string.IsNullOrWhiteSpace(mapping.Description) ? mapping.Description : mapping.Title ?? string.Empty,
|
||||
Request = MapRequest(mapping.Request, path),
|
||||
Response = MapResponse(mapping.Response)
|
||||
};
|
||||
|
||||
@@ -66,6 +66,7 @@ public partial class WireMockServer
|
||||
public RegexMatcher MappingsCodeGuidPathMatcher => new($"^{_prefixEscaped}\\/mappings\\/code\\/([0-9A-Fa-f]{{8}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{12}})$");
|
||||
public RegexMatcher RequestsGuidPathMatcher => new($"^{_prefixEscaped}\\/requests\\/([0-9A-Fa-f]{{8}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{4}}[-][0-9A-Fa-f]{{12}})$");
|
||||
public RegexMatcher ScenariosNameMatcher => new($"^{_prefixEscaped}\\/scenarios\\/.+$");
|
||||
public RegexMatcher ScenariosNameWithStateMatcher => new($"^{_prefixEscaped}\\/scenarios\\/.+\\/state$");
|
||||
public RegexMatcher ScenariosNameWithResetMatcher => new($"^{_prefixEscaped}\\/scenarios\\/.+\\/reset$");
|
||||
public RegexMatcher FilesFilenamePathMatcher => new($"^{_prefixEscaped}\\/files\\/.+$");
|
||||
public RegexMatcher ProtoDefinitionsIdPathMatcher => new($"^{_prefixEscaped}\\/protodefinitions\\/.+$");
|
||||
@@ -138,6 +139,9 @@ public partial class WireMockServer
|
||||
Given(Request.Create().WithPath(_adminPaths.Scenarios + "/reset").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosReset));
|
||||
Given(Request.Create().WithPath(_adminPaths.ScenariosNameWithResetMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenarioReset));
|
||||
|
||||
// __admin/scenarios/{scenario}/state
|
||||
Given(Request.Create().WithPath(_adminPaths.ScenariosNameWithStateMatcher).UsingPut()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(ScenariosSetState));
|
||||
|
||||
// __admin/files/{filename}
|
||||
Given(Request.Create().WithPath(_adminPaths.FilesFilenamePathMatcher).UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePost));
|
||||
Given(Request.Create().WithPath(_adminPaths.FilesFilenamePathMatcher).UsingPut()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(FilePut));
|
||||
@@ -705,6 +709,21 @@ public partial class WireMockServer
|
||||
ResponseMessageBuilder.Create(200, "Scenario reset") :
|
||||
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
|
||||
}
|
||||
|
||||
private IResponseMessage ScenariosSetState(IRequestMessage requestMessage)
|
||||
{
|
||||
var name = requestMessage.Path.Split('/').Reverse().Skip(1).First();
|
||||
if (!_options.Scenarios.ContainsKey(name))
|
||||
{
|
||||
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
|
||||
}
|
||||
|
||||
var update = DeserializeObject<ScenarioStateUpdateModel>(requestMessage);
|
||||
|
||||
return SetScenarioState(name, update.State) ?
|
||||
ResponseMessageBuilder.Create(200, $"Scenario state set to '{update.State}'") :
|
||||
ResponseMessageBuilder.Create(HttpStatusCode.NotFound, $"No scenario found by name '{name}'.");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Pact
|
||||
|
||||
@@ -76,6 +76,11 @@ public partial class WireMockServer
|
||||
respondProvider = respondProvider.WithTitle(mappingModel.Title!);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(mappingModel.Description))
|
||||
{
|
||||
respondProvider = respondProvider.WithDescription(mappingModel.Description!);
|
||||
}
|
||||
|
||||
if (mappingModel.Priority != null)
|
||||
{
|
||||
respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
|
||||
|
||||
@@ -120,6 +120,32 @@ public partial class WireMockServer : IWireMockServer
|
||||
#endregion
|
||||
|
||||
#region HttpClient
|
||||
#if NET5_0_OR_GREATER
|
||||
private readonly Lazy<IHttpClientFactory> _lazyHttpClientFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="IHttpClientFactory"/> which can be used to generate a HttpClient to call this instance.
|
||||
/// <param name="handlers">
|
||||
/// An ordered list of System.Net.Http.DelegatingHandler instances to be invoked
|
||||
/// as an System.Net.Http.HttpRequestMessage travels from the System.Net.Http.HttpClient
|
||||
/// to the network and an System.Net.Http.HttpResponseMessage travels from the network
|
||||
/// back to System.Net.Http.HttpClient. The handlers are invoked in a top-down fashion.
|
||||
/// That is, the first entry is invoked first for an outbound request message but
|
||||
/// last for an inbound response message.
|
||||
/// </param>
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public IHttpClientFactory CreateHttpClientFactory(params DelegatingHandler[] handlers)
|
||||
{
|
||||
if (!IsStarted)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to create IHttpClientFactory because the service is not started.");
|
||||
}
|
||||
|
||||
return handlers.Length > 0 ? new WireMockHttpClientFactory(this, handlers) : _lazyHttpClientFactory.Value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Create a <see cref="HttpClient"/> which can be used to call this instance.
|
||||
/// <param name="handlers">
|
||||
@@ -427,6 +453,10 @@ public partial class WireMockServer : IWireMockServer
|
||||
}
|
||||
|
||||
InitSettings(settings);
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
_lazyHttpClientFactory = new Lazy<IHttpClientFactory>(() => new WireMockHttpClientFactory(this));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.Stop" />
|
||||
@@ -567,6 +597,32 @@ public partial class WireMockServer : IWireMockServer
|
||||
return _options.Scenarios.ContainsKey(name) && _options.Scenarios.TryRemove(name, out _);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public bool SetScenarioState(string name, string? state)
|
||||
{
|
||||
if (state == null)
|
||||
{
|
||||
return ResetScenario(name);
|
||||
}
|
||||
|
||||
_options.Scenarios.AddOrUpdate(
|
||||
name,
|
||||
_ => new ScenarioState
|
||||
{
|
||||
Name = name,
|
||||
NextState = state
|
||||
},
|
||||
(_, current) =>
|
||||
{
|
||||
current.NextState = state;
|
||||
return current;
|
||||
}
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IWireMockServer.WithMapping(MappingModel[])" />
|
||||
[PublicAPI]
|
||||
public IWireMockServer WithMapping(params MappingModel[] mappings)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using HandlebarsDotNet;
|
||||
using HandlebarsDotNet.Helpers.Extensions;
|
||||
using Stef.Validation;
|
||||
@@ -9,6 +10,8 @@ namespace WireMock.Transformers.Handlebars;
|
||||
|
||||
internal class HandlebarsContext : IHandlebarsContext
|
||||
{
|
||||
private static readonly Regex _tryEvaluateRegex = new(@"\{\{.*?\}\}", RegexOptions.Compiled);
|
||||
|
||||
public IHandlebars Handlebars { get; }
|
||||
|
||||
public IFileSystemHandler FileSystemHandler { get; }
|
||||
@@ -27,9 +30,8 @@ internal class HandlebarsContext : IHandlebarsContext
|
||||
|
||||
public object? ParseAndEvaluate(string text, object model)
|
||||
{
|
||||
if (text.StartsWith("{{") && text.EndsWith("}}") &&
|
||||
Handlebars.TryEvaluate(text, model, out var result) &&
|
||||
result is not UndefinedBindingResult)
|
||||
// Only try to evaluate if the text matches the pattern `{{ xxx }}` exactly once.
|
||||
if (_tryEvaluateRegex.Matches(text).Count == 1 && Handlebars.TryEvaluate(text, model, out var result) && result is not UndefinedBindingResult)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HandlebarsDotNet.Helpers.Models;
|
||||
@@ -170,8 +171,8 @@ internal class Transformer : ITransformer
|
||||
WalkNode(transformerContext, options, jToken, model);
|
||||
break;
|
||||
|
||||
case Array bodyAsArray:
|
||||
jToken = JArray.FromObject(bodyAsArray, _jsonSerializer);
|
||||
case var bodyAsEnumerable when bodyAsEnumerable is IEnumerable and not string:
|
||||
jToken = JArray.FromObject(bodyAsEnumerable, _jsonSerializer);
|
||||
WalkNode(transformerContext, options, jToken, model);
|
||||
break;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ internal static class TypeLoader
|
||||
{
|
||||
var key = typeof(TInterface).FullName!;
|
||||
|
||||
var pluginType = Assemblies.GetOrAdd(key, _ =>
|
||||
return Assemblies.GetOrAdd(key, _ =>
|
||||
{
|
||||
if (TryFindTypeInDlls<TInterface>(null, out var foundType))
|
||||
{
|
||||
@@ -60,7 +60,6 @@ internal static class TypeLoader
|
||||
|
||||
throw new DllNotFoundException($"No dll found which implements interface '{key}'.");
|
||||
});
|
||||
return pluginType;
|
||||
}
|
||||
|
||||
private static Type GetPluginTypeByFullName<TInterface>(string implementationTypeFullName) where TInterface : class
|
||||
@@ -68,7 +67,7 @@ internal static class TypeLoader
|
||||
var @interface = typeof(TInterface).FullName;
|
||||
var key = $"{@interface}_{implementationTypeFullName}";
|
||||
|
||||
var pluginType = Assemblies.GetOrAdd(key, _ =>
|
||||
return Assemblies.GetOrAdd(key, _ =>
|
||||
{
|
||||
if (TryFindTypeInDlls<TInterface>(implementationTypeFullName, out var foundType))
|
||||
{
|
||||
@@ -77,28 +76,40 @@ internal static class TypeLoader
|
||||
|
||||
throw new DllNotFoundException($"No dll found which implements Interface '{@interface}' and has FullName '{implementationTypeFullName}'.");
|
||||
});
|
||||
return pluginType;
|
||||
}
|
||||
|
||||
private static bool TryFindTypeInDlls<TInterface>(string? implementationTypeFullName, [NotNullWhen(true)] out Type? pluginType) where TInterface : class
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.dll"))
|
||||
#if NETSTANDARD1_3
|
||||
var directoriesToSearch = new[] { AppContext.BaseDirectory };
|
||||
#else
|
||||
var processDirectory = Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName);
|
||||
var assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
var directoriesToSearch = new[] { processDirectory, assemblyDirectory }
|
||||
.Where(d => !string.IsNullOrEmpty(d))
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
#endif
|
||||
foreach (var directory in directoriesToSearch)
|
||||
{
|
||||
try
|
||||
foreach (var file in Directory.GetFiles(directory!, "*.dll"))
|
||||
{
|
||||
var assembly = Assembly.Load(new AssemblyName
|
||||
try
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(file)
|
||||
});
|
||||
var assembly = Assembly.Load(new AssemblyName
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(file)
|
||||
});
|
||||
|
||||
if (TryGetImplementationTypeByInterfaceAndOptionalFullName<TInterface>(assembly, implementationTypeFullName, out pluginType))
|
||||
{
|
||||
return true;
|
||||
if (TryGetImplementationTypeByInterfaceAndOptionalFullName<TInterface>(assembly, implementationTypeFullName, out pluginType))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// no-op: just try next .dll
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// no-op: just try next .dll
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<PackageReference Include="JmesPath.Net" Version="1.0.330" />
|
||||
<PackageReference Include="AnyOf" Version="0.4.0" />
|
||||
<PackageReference Include="TinyMapper.Signed" Version="4.0.0" />
|
||||
<PackageReference Include="PolySharp" Version="1.15.0">
|
||||
<PackageReference Include="Nullable" Version="1.3.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
@@ -157,13 +157,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.5.0" />
|
||||
<!--<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.5.0" />-->
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.5.0" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.5.0" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.5.0" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.5.0" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.5.0" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers" Version="2.5.2" />
|
||||
<!--<PackageReference Include="Handlebars.Net.Helpers.DynamicLinq" Version="2.5.2" />-->
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Humanizer" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Json" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Random" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.Xeger" Version="2.5.2" />
|
||||
<PackageReference Include="Handlebars.Net.Helpers.XPath" Version="2.5.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' ">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="RamlToOpenApiConverter.SourceOnly" Version="0.8.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="8.1.0" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.18" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -256,7 +256,7 @@ public interface IWireMockAdminApi
|
||||
/// Delete (reset) all scenarios
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Post("scenarios")]
|
||||
[Post("scenarios/reset")]
|
||||
Task<StatusModel> ResetScenariosAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
@@ -269,7 +269,7 @@ public interface IWireMockAdminApi
|
||||
Task<StatusModel> DeleteScenarioAsync([Path] string name, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Delete (reset) all scenarios
|
||||
/// Delete (reset) a specific scenario
|
||||
/// </summary>
|
||||
/// <param name="name">Scenario name.</param>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
@@ -277,6 +277,16 @@ public interface IWireMockAdminApi
|
||||
[AllowAnyStatusCode]
|
||||
Task<StatusModel> ResetScenarioAsync([Path] string name, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Update the state for a scenario.
|
||||
/// </summary>
|
||||
/// <param name="name">Scenario name.</param>
|
||||
/// <param name="updateModel">Scenario state update model.</param>
|
||||
/// <param name="cancellationToken">The optional cancellationToken.</param>
|
||||
[Put("scenarios/{name}/state")]
|
||||
[AllowAnyStatusCode]
|
||||
Task<StatusModel> PutScenarioStateAsync([Path] string name, [Body] ScenarioStateUpdateModel updateModel, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new File
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
@@ -33,5 +35,5 @@ public interface IMimePartMatcher : IMatcher
|
||||
/// </summary>
|
||||
/// <param name="value">The MimePart.</param>
|
||||
/// <returns>A value between 0.0 - 1.0 of the similarity.</returns>
|
||||
public MatchResult IsMatch(object value);
|
||||
public MatchResult IsMatch(IMimePartData value);
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using WireMock.Models.Mime;
|
||||
|
||||
namespace WireMock.Util;
|
||||
|
||||
@@ -12,24 +12,16 @@ namespace WireMock.Util;
|
||||
public interface IMimeKitUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Loads the MimeKit.MimeMessage from the stream.
|
||||
/// Loads the <see cref="IMimeMessageData"/> from the stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream</param>
|
||||
/// <returns>MimeKit.MimeMessage</returns>
|
||||
object LoadFromStream(Stream stream);
|
||||
IMimeMessageData LoadFromStream(Stream stream);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to get the MimeKit.MimeMessage from the request message.
|
||||
/// Tries to get the <see cref="IMimeMessageData"/> from the request message.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The request message.</param>
|
||||
/// <param name="mimeMessage">The MimeKit.MimeMessage</param>
|
||||
/// <param name="mimeMessageData">A class MimeMessageDataWrapper which wraps a MimeKit.MimeMessage.</param>
|
||||
/// <returns><c>true</c> when parsed correctly, else <c>false</c></returns>
|
||||
bool TryGetMimeMessage(IRequestMessage requestMessage, [NotNullWhen(true)] out object? mimeMessage);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the body parts from the MimeKit.MimeMessage.
|
||||
/// </summary>
|
||||
/// <param name="mimeMessage">The MimeKit.MimeMessage.</param>
|
||||
/// <returns>A list of MimeParts.</returns>
|
||||
IReadOnlyList<object> GetBodyParts(object mimeMessage);
|
||||
bool TryGetMimeMessage(IRequestMessage requestMessage, [NotNullWhen(true)] out IMimeMessageData? mimeMessageData);
|
||||
}
|
||||
@@ -39,11 +39,11 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
||||
<PackageReference Include="Testcontainers" Version="4.0.0" />
|
||||
<PackageReference Include="Testcontainers" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.RestClient\WireMock.Net.RestClient.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,39 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DefineConstants>$(DefineConstants);GRAPHQL;MIMEKIT;PROTOBUF</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AwesomeAssertions" Version="9.0.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="WireMock.Net" Version="1.8.11" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="SonarAnalyzer.CSharp" Version="10.11.0.117924" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,103 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using AwesomeAssertions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace WireMock.Net.Tests;
|
||||
|
||||
public partial class WireMockServerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithMultiPartBody_Using_MimePartMatchers()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.Start();
|
||||
|
||||
var textPlainContent = "This is some plain text";
|
||||
var textPlainContentType = "text/plain";
|
||||
var textPlainContentTypeMatcher = new ContentTypeMatcher(textPlainContentType);
|
||||
var textPlainContentMatcher = new ExactMatcher(textPlainContent);
|
||||
var textPlainMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textPlainContentTypeMatcher, null, null, textPlainContentMatcher);
|
||||
|
||||
var textJson = "{ \"Key\" : \"Value\" }";
|
||||
var textJsonContentType = "text/json";
|
||||
var textJsonContentTypeMatcher = new ContentTypeMatcher(textJsonContentType);
|
||||
var textJsonContentMatcher = new JsonMatcher(new { Key = "Value" }, true);
|
||||
var jsonMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, textJsonContentTypeMatcher, null, null, textJsonContentMatcher);
|
||||
|
||||
var imagePngBytes = Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACAgMAAAAP2OW3AAAADFBMVEX/tID/vpH/pWX/sHidUyjlAAAADElEQVR4XmMQYNgAAADkAMHebX3mAAAAAElFTkSuQmCC");
|
||||
var imagePngContentMatcher = new ExactObjectMatcher(imagePngBytes);
|
||||
var imagePngMatcher = new MimePartMatcher(MatchBehaviour.AcceptOnMatch, null, null, null, imagePngContentMatcher);
|
||||
|
||||
var matchers = new IMatcher[]
|
||||
{
|
||||
textPlainMatcher,
|
||||
jsonMatcher,
|
||||
imagePngMatcher
|
||||
};
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/multipart")
|
||||
.WithMultiPart(matchers)
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("{{request.Method}};{{request.BodyAsMimeMessage.TextBody}}")
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/multipart2")
|
||||
.WithMultiPart(matchers)
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody(request =>
|
||||
{
|
||||
if (request.BodyAsMimeMessage == null)
|
||||
{
|
||||
throw new InvalidProgramException("Not expected");
|
||||
}
|
||||
return "OK";
|
||||
})
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
var formDataContent = new MultipartFormDataContent
|
||||
{
|
||||
{ new StringContent(textPlainContent, Encoding.UTF8, textPlainContentType), "text" },
|
||||
{ new StringContent(textJson, Encoding.UTF8, textJsonContentType), "json" }
|
||||
};
|
||||
|
||||
var fileContent = new ByteArrayContent(imagePngBytes);
|
||||
fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/png");
|
||||
formDataContent.Add(fileContent, "somefile", "image.png");
|
||||
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act 1
|
||||
var response1 = await client.PostAsync("/multipart", formDataContent);
|
||||
|
||||
// Assert 1
|
||||
response1.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
var content1 = await response1.Content.ReadAsStringAsync();
|
||||
content1.Should().Be("POST;This is some plain text");
|
||||
|
||||
// Act 2
|
||||
var response2 = await client.PostAsync("/multipart2", formDataContent);
|
||||
|
||||
// Assert 1
|
||||
response2.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
var content2 = await response2.Content.ReadAsStringAsync();
|
||||
content2.Should().Be("OK");
|
||||
}
|
||||
}
|
||||
@@ -62,13 +62,15 @@ public partial class WireMockAdminApiTests
|
||||
{
|
||||
Request = new RequestModel { Path = "/1" },
|
||||
Response = new ResponseModel { Body = "txt 1" },
|
||||
Title = "test 1"
|
||||
Title = "test 1",
|
||||
Description = "description 1"
|
||||
};
|
||||
var model2 = new MappingModel
|
||||
{
|
||||
Request = new RequestModel { Path = "/2" },
|
||||
Response = new ResponseModel { Body = "txt 2" },
|
||||
Title = "test 2"
|
||||
Title = "test 2",
|
||||
Description = "description 2"
|
||||
};
|
||||
var result = await api.PostMappingsAsync(new[] { model1, model2 }).ConfigureAwait(false);
|
||||
|
||||
@@ -77,6 +79,8 @@ public partial class WireMockAdminApiTests
|
||||
Check.That(result.Status).IsNotNull();
|
||||
Check.That(result.Guid).IsNull();
|
||||
Check.That(server.Mappings.Where(m => !m.IsAdminInterface)).HasSize(2);
|
||||
Check.That(server.Mappings.Single(x => x.Title == "test 1").Description).IsEqualTo("description 1");
|
||||
Check.That(server.Mappings.Single(x => x.Title == "test 2").Description).IsEqualTo("description 2");
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ using RestEase;
|
||||
using VerifyTests;
|
||||
using VerifyXunit;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Admin.Scenarios;
|
||||
using WireMock.Admin.Settings;
|
||||
using WireMock.Client;
|
||||
using WireMock.Client.Extensions;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
using WireMock.Net.Tests.VerifyExtensions;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
@@ -184,7 +184,7 @@ public partial class WireMockAdminApiTests
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task IWireMockAdminApi_FindRequestsAsync()
|
||||
@@ -743,6 +743,57 @@ public partial class WireMockAdminApiTests
|
||||
status.Status.Should().Be("No scenario found by name 'x'.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IWireMockAdminApi_UpdateNonExistingScenarioState()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.StartWithAdminInterface();
|
||||
|
||||
var api = RestClient.For<IWireMockAdminApi>(server.Urls[0]);
|
||||
|
||||
// Act
|
||||
var update = new ScenarioStateUpdateModel
|
||||
{
|
||||
State = null
|
||||
};
|
||||
var status = await api.PutScenarioStateAsync("x", update).ConfigureAwait(false);
|
||||
status.Status.Should().Be("No scenario found by name 'x'.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IWireMockAdminApi_UpdateScenarioState()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.StartWithAdminInterface();
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.WithPath("/state1")
|
||||
.UsingGet())
|
||||
.InScenario("s1")
|
||||
.WillSetStateTo("Test state 1")
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("No state msg 1"));
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.WithPath("/foostate1")
|
||||
.UsingGet())
|
||||
.InScenario("s1")
|
||||
.WhenStateIs("Test state 1")
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("Test state msg 1"));
|
||||
|
||||
var api = RestClient.For<IWireMockAdminApi>(server.Urls[0]);
|
||||
|
||||
// Act
|
||||
var update = new ScenarioStateUpdateModel
|
||||
{
|
||||
State = null
|
||||
};
|
||||
var status = await api.PutScenarioStateAsync("s1", update).ConfigureAwait(false);
|
||||
status.Status.Should().Be("Scenario state set to ''");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task IWireMockAdminApi_GetMappingByGuidAsync()
|
||||
{
|
||||
|
||||
@@ -15,6 +15,19 @@
|
||||
Methods: [
|
||||
POST
|
||||
],
|
||||
Headers: [
|
||||
{
|
||||
Name: Authorization,
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: *,
|
||||
IgnoreCase: false,
|
||||
RejectOnMatch: true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
Body: {
|
||||
Matcher: {
|
||||
Name: JsonPartialMatcher,
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using VerifyTests;
|
||||
using VerifyXunit;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Client;
|
||||
using WireMock.Client.Extensions;
|
||||
using WireMock.Net.Tests.VerifyExtensions;
|
||||
@@ -41,6 +42,7 @@ public class AdminApiMappingBuilderTests
|
||||
.WithRequest(req => req
|
||||
.UsingPost()
|
||||
.WithPath("/bla1")
|
||||
.WithHeader("Authorization", "*", true)
|
||||
.WithBody(body => body
|
||||
.WithMatcher(matcher => matcher
|
||||
.WithName("JsonPartialMatcher")
|
||||
|
||||
@@ -6,5 +6,5 @@ internal static class Constants
|
||||
{
|
||||
internal const int NumStaticMappings = 10;
|
||||
|
||||
internal const int NumAdminMappings = 36;
|
||||
internal const int NumAdminMappings = 37;
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public class MimePartMatcherTests
|
||||
{
|
||||
// Arrange
|
||||
var message = MimeKitUtils.LoadFromStream(StreamUtils.CreateStream(TestMultiPart));
|
||||
var part = MimeKitUtils.GetBodyParts(message)[0];
|
||||
var part = message.BodyParts[0];
|
||||
|
||||
// Act
|
||||
var contentTypeMatcher = new ContentTypeMatcher("text/plain");
|
||||
@@ -67,7 +67,7 @@ public class MimePartMatcherTests
|
||||
{
|
||||
// Arrange
|
||||
var message = MimeKitUtils.LoadFromStream(StreamUtils.CreateStream(TestMultiPart));
|
||||
var part = MimeKitUtils.GetBodyParts(message)[1];
|
||||
var part = message.BodyParts[1];
|
||||
|
||||
// Act
|
||||
var contentTypeMatcher = new ContentTypeMatcher("text/json");
|
||||
@@ -85,7 +85,7 @@ public class MimePartMatcherTests
|
||||
{
|
||||
// Arrange
|
||||
var message = MimeKitUtils.LoadFromStream(StreamUtils.CreateStream(TestMultiPart));
|
||||
var part = MimeKitUtils.GetBodyParts(message)[2];
|
||||
var part = message.BodyParts[2];
|
||||
|
||||
// Act
|
||||
var contentTypeMatcher = new ContentTypeMatcher("image/png");
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"consumer": {
|
||||
"name": "Something API Consumer Get"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "A GET request to retrieve the something",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Accept": "application/json"
|
||||
},
|
||||
"method": "GET",
|
||||
"path": "/tester",
|
||||
"query": "q1=test&q2=ok"
|
||||
},
|
||||
"response": {
|
||||
"body": {
|
||||
"id": "tester",
|
||||
"firstName": "Totally",
|
||||
"lastName": "Awesome"
|
||||
},
|
||||
"headers": {
|
||||
"Content-Type": "application/json; charset=utf-8"
|
||||
},
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
],
|
||||
"provider": {
|
||||
"name": "Something API"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"consumer": {
|
||||
"name": "Default Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "A POST request to change something",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"path": "/tester"
|
||||
},
|
||||
"response": {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
],
|
||||
"provider": {
|
||||
"name": "Default Provider"
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
#if !(NET452 || NET461 || NETCOREAPP3_1)
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using VerifyXunit;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
@@ -14,10 +17,11 @@ using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Pact;
|
||||
|
||||
[UsesVerify]
|
||||
public class PactTests
|
||||
{
|
||||
[Fact]
|
||||
public void SavePact_Get_Request_And_Response_WithBodyAsJson()
|
||||
public async Task SavePact_Get_Request_And_Response_WithBodyAsJson()
|
||||
{
|
||||
var server = WireMockServer.Start();
|
||||
server
|
||||
@@ -46,12 +50,34 @@ public class PactTests
|
||||
|
||||
var folder = Path.Combine("../../../", "Pact", "files");
|
||||
var file = "pact-get.json";
|
||||
var path = Path.Combine(folder, file);
|
||||
|
||||
// Act
|
||||
server.SavePact(folder, file);
|
||||
|
||||
// Assert
|
||||
File.ReadAllBytes(Path.Combine(folder, file)).Length.Should().BeGreaterThan(1);
|
||||
await Verifier.VerifyFile(path);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SavePact_Post_Request_WithDescription()
|
||||
{
|
||||
var server = WireMockServer.Start();
|
||||
server
|
||||
.Given(Request.Create().UsingPost().WithPath("/tester"))
|
||||
.WithTitle("POST something")
|
||||
.WithDescription("A POST request to change something")
|
||||
.RespondWith(Response.Create().WithStatusCode(HttpStatusCode.OK));
|
||||
|
||||
var folder = Path.Combine("../../../", "Pact", "files");
|
||||
var file = "pact-post.json";
|
||||
var path = Path.Combine(folder, file);
|
||||
|
||||
// Act
|
||||
server.SavePact(folder, file);
|
||||
|
||||
// Assert
|
||||
await Verifier.VerifyFile(path);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -219,4 +245,5 @@ public class PactTests
|
||||
// Assert
|
||||
File.ReadAllBytes(Path.Combine(folder, file)).Length.Should().BeGreaterThan(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -4,7 +4,7 @@
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"providerState": "A GET request to retrieve the something",
|
||||
"description": "A GET request to retrieve the something",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Accept": "application/json"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"providerState": "A GET request to retrieve the something",
|
||||
"description": "A GET request to retrieve the something",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Accept": "application/json"
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"providerState": "A Post request to add the something",
|
||||
"description": "A Post request to add the something",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Accept": "application/json"
|
||||
|
||||
20
test/WireMock.Net.Tests/Pact/files/pact-post.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"consumer": {
|
||||
"name": "Default Consumer"
|
||||
},
|
||||
"interactions": [
|
||||
{
|
||||
"description": "A POST request to change something",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"path": "/tester"
|
||||
},
|
||||
"response": {
|
||||
"status": 200
|
||||
}
|
||||
}
|
||||
],
|
||||
"provider": {
|
||||
"name": "Default Provider"
|
||||
}
|
||||
}
|
||||
@@ -120,21 +120,21 @@ public class ResponseWithTransformerTests
|
||||
var request = new RequestMessage(urlDetails, "POST", ClientIp);
|
||||
|
||||
var responseBuilder = Response.Create()
|
||||
.WithBody("{{request.PathSegments.[0]}} {{request.AbsolutePathSegments.[0]}}")
|
||||
.WithBody("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}} {{request.AbsolutePathSegments.[0]}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
Check.That(response.Message.BodyData!.BodyAsString).Equals("a wiremock");
|
||||
Check.That(response.Message.BodyData!.BodyAsString).Equals("a b wiremock");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("{{request.PathSegments.[0]}}", "a")]
|
||||
[InlineData("prefix_{{request.PathSegments.[0]}}", "prefix_a")]
|
||||
[InlineData("{{request.PathSegments.[0]}}_postfix", "a_postfix")]
|
||||
[InlineData("prefix_{{request.PathSegments.[0]}}_postfix", "prefix_a_postfix")]
|
||||
[InlineData("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}", "a b")]
|
||||
[InlineData("prefix_{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}", "prefix_a b")]
|
||||
[InlineData("{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}_postfix", "a b_postfix")]
|
||||
[InlineData("prefix_{{request.PathSegments.[0]}} {{request.PathSegments.[1]}}_postfix", "prefix_a b_postfix")]
|
||||
public async Task Response_ProvideResponse_Handlebars_BodyAsJson_PathSegments(string field, string expected)
|
||||
{
|
||||
// Assign
|
||||
|
||||
@@ -12,340 +12,447 @@ using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests
|
||||
namespace WireMock.Net.Tests;
|
||||
|
||||
public class StatefulBehaviorTests
|
||||
{
|
||||
public class StatefulBehaviorTests
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_skip_non_relevant_states()
|
||||
{
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_skip_non_relevant_states()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WhenStateIs("Test state")
|
||||
.RespondWith(Response.Create());
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WhenStateIs("Test state")
|
||||
.RespondWith(Response.Create());
|
||||
|
||||
// when
|
||||
var response = await new HttpClient().GetAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
// when
|
||||
var response = await new HttpClient().GetAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
|
||||
// then
|
||||
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
|
||||
// then
|
||||
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_process_request_if_equals_state_and_single_state_defined()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_process_request_if_equals_state_and_single_state_defined()
|
||||
{
|
||||
// Arrange
|
||||
var path = $"/foo_{Guid.NewGuid()}";
|
||||
using var server = WireMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WillSetStateTo("Test state")
|
||||
.RespondWith(Response.Create().WithBody("No state msg"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WillSetStateTo("Test state")
|
||||
.RespondWith(Response.Create().WithBody("No state msg"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WhenStateIs("Test state")
|
||||
.RespondWith(Response.Create().WithBody("Test state msg"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("s")
|
||||
.WhenStateIs("Test state")
|
||||
.RespondWith(Response.Create().WithBody("Test state msg"));
|
||||
|
||||
// when
|
||||
var responseNoState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
// Act
|
||||
var responseNoState = await new HttpClient().GetStringAsync(server.Url + path).ConfigureAwait(false);
|
||||
var responseWithState = await new HttpClient().GetStringAsync(server.Url + path).ConfigureAwait(false);
|
||||
|
||||
// then
|
||||
Check.That(responseNoState).Equals("No state msg");
|
||||
Check.That(responseWithState).Equals("Test state msg");
|
||||
// Assert
|
||||
Check.That(responseNoState).Equals("No state msg");
|
||||
Check.That(responseWithState).Equals("Test state msg");
|
||||
}
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
[Theory]
|
||||
[InlineData(null, "step 1", "step 2")]
|
||||
[InlineData("step 2", "step 2", "step 3")]
|
||||
public async Task Scenarios_Should_ContinueOnCorrectState_WhenStateIsUpdated(string? state, string expected1, string expected2)
|
||||
{
|
||||
// Arrange
|
||||
var path = $"/foo_{Guid.NewGuid()}";
|
||||
var scenario = "s";
|
||||
using var server = WireMockServer.Start();
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_With_Same_Path_Should_Use_Times_When_Moving_To_Next_State()
|
||||
{
|
||||
// given
|
||||
const int times = 2;
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
string body1 = "Scenario S1, No State, Setting State T2";
|
||||
string body2 = "Scenario S1, State T2, End";
|
||||
var server = WireMockServer.Start();
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WillSetStateTo("step 2")
|
||||
.RespondWith(Response.Create().WithBody("step 1"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo(2, times)
|
||||
.RespondWith(Response.Create().WithBody(body1));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WhenStateIs("step 2")
|
||||
.WillSetStateTo("step 3")
|
||||
.RespondWith(Response.Create().WithBody("step 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WhenStateIs(2)
|
||||
.RespondWith(Response.Create().WithBody(body2));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WhenStateIs("step 3")
|
||||
.RespondWith(Response.Create().WithBody("step 3"));
|
||||
|
||||
// when
|
||||
var client = new HttpClient();
|
||||
var responseScenario1 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseScenario2 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithState = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
// Act
|
||||
var client = server.CreateClient();
|
||||
var response1 = await client.GetStringAsync(server.Url + path);
|
||||
var response2 = await client.GetStringAsync(server.Url + path);
|
||||
var response3 = await client.GetStringAsync(server.Url + path);
|
||||
|
||||
// then
|
||||
responseScenario1.Should().Be(body1);
|
||||
responseScenario2.Should().Be(body1);
|
||||
responseWithState.Should().Be(body2);
|
||||
server.SetScenarioState(scenario, state);
|
||||
var responseA = await client.GetStringAsync(server.Url + path);
|
||||
var responseB = await client.GetStringAsync(server.Url + path);
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
// Assert
|
||||
Check.That(response1).Equals("step 1");
|
||||
Check.That(response2).Equals("step 2");
|
||||
Check.That(response3).Equals("step 3");
|
||||
Check.That(responseA).Equals(expected1);
|
||||
Check.That(responseB).Equals(expected2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_With_Different_Paths_Should_Use_Times_When_Moving_To_Next_State()
|
||||
{
|
||||
// given
|
||||
const int times = 2;
|
||||
string path1 = $"/a_{Guid.NewGuid()}";
|
||||
string path2 = $"/b_{Guid.NewGuid()}";
|
||||
string path3 = $"/c_{Guid.NewGuid()}";
|
||||
string body1 = "Scenario S1, No State, Setting State T2";
|
||||
string body2 = "Scenario S1, State T2, Setting State T3";
|
||||
string body3 = "Scenario S1, State T3, End";
|
||||
[Fact]
|
||||
public async Task Scenarios_With_Same_Path_Should_Use_Times_When_Moving_To_Next_State()
|
||||
{
|
||||
// given
|
||||
const int times = 2;
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
string body1 = "Scenario S1, No State, Setting State T2";
|
||||
string body2 = "Scenario S1, State T2, End";
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
var server = WireMockServer.Start();
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo(2, times)
|
||||
.RespondWith(Response.Create().WithBody(body1));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path1).UsingGet())
|
||||
.InScenario("S1")
|
||||
.WillSetStateTo("T2", times)
|
||||
.RespondWith(Response.Create().WithBody(body1));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WhenStateIs(2)
|
||||
.RespondWith(Response.Create().WithBody(body2));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path2).UsingGet())
|
||||
.InScenario("S1")
|
||||
.WhenStateIs("T2")
|
||||
.WillSetStateTo("T3", times)
|
||||
.RespondWith(Response.Create().WithBody(body2));
|
||||
// when
|
||||
var client = new HttpClient();
|
||||
var responseScenario1 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseScenario2 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithState = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path3).UsingGet())
|
||||
.InScenario("S1")
|
||||
.WhenStateIs("T3")
|
||||
.RespondWith(Response.Create().WithBody(body3));
|
||||
// then
|
||||
responseScenario1.Should().Be(body1);
|
||||
responseScenario2.Should().Be(body1);
|
||||
responseWithState.Should().Be(body2);
|
||||
|
||||
// when
|
||||
var client = new HttpClient();
|
||||
var t1a = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path1).ConfigureAwait(false);
|
||||
var t1b = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path1).ConfigureAwait(false);
|
||||
var t2a = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path2).ConfigureAwait(false);
|
||||
var t2b = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path2).ConfigureAwait(false);
|
||||
var t3 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path3).ConfigureAwait(false);
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
// then
|
||||
t1a.Should().Be(body1);
|
||||
t1b.Should().Be(body1);
|
||||
t2a.Should().Be(body2);
|
||||
t2b.Should().Be(body2);
|
||||
t3.Should().Be(body3);
|
||||
[Fact]
|
||||
public async Task Scenarios_With_Different_Paths_Should_Use_Times_When_Moving_To_Next_State()
|
||||
{
|
||||
// given
|
||||
const int times = 2;
|
||||
string path1 = $"/a_{Guid.NewGuid()}";
|
||||
string path2 = $"/b_{Guid.NewGuid()}";
|
||||
string path3 = $"/c_{Guid.NewGuid()}";
|
||||
string body1 = "Scenario S1, No State, Setting State T2";
|
||||
string body2 = "Scenario S1, State T2, Setting State T3";
|
||||
string body3 = "Scenario S1, State T3, End";
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Int_Valued_Scenarios_and_States()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
server
|
||||
.Given(Request.Create().WithPath(path1).UsingGet())
|
||||
.InScenario("S1")
|
||||
.WillSetStateTo("T2", times)
|
||||
.RespondWith(Response.Create().WithBody(body1));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo(2)
|
||||
.RespondWith(Response.Create().WithBody("Scenario 1, Setting State 2"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path2).UsingGet())
|
||||
.InScenario("S1")
|
||||
.WhenStateIs("T2")
|
||||
.WillSetStateTo("T3", times)
|
||||
.RespondWith(Response.Create().WithBody(body2));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WhenStateIs(2)
|
||||
.RespondWith(Response.Create().WithBody("Scenario 1, State 2"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path3).UsingGet())
|
||||
.InScenario("S1")
|
||||
.WhenStateIs("T3")
|
||||
.RespondWith(Response.Create().WithBody(body3));
|
||||
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
// when
|
||||
var client = new HttpClient();
|
||||
var t1a = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path1).ConfigureAwait(false);
|
||||
var t1b = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path1).ConfigureAwait(false);
|
||||
var t2a = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path2).ConfigureAwait(false);
|
||||
var t2b = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path2).ConfigureAwait(false);
|
||||
var t3 = await client.GetStringAsync("http://localhost:" + server.Ports[0] + path3).ConfigureAwait(false);
|
||||
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("Scenario 1, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("Scenario 1, State 2");
|
||||
// then
|
||||
t1a.Should().Be(body1);
|
||||
t1b.Should().Be(body1);
|
||||
t2a.Should().Be(body2);
|
||||
t2b.Should().Be(body2);
|
||||
t3.Should().Be(body3);
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Mixed_String_Scenario_and_Int_State()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Int_Valued_Scenarios_and_States()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("state string")
|
||||
.WillSetStateTo(1)
|
||||
.RespondWith(Response.Create().WithBody("string state, Setting State 2"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo(2)
|
||||
.RespondWith(Response.Create().WithBody("Scenario 1, Setting State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("state string")
|
||||
.WhenStateIs(1)
|
||||
.RespondWith(Response.Create().WithBody("string state, State 2"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WhenStateIs(2)
|
||||
.RespondWith(Response.Create().WithBody("Scenario 1, State 2"));
|
||||
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("string state, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("string state, State 2");
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("Scenario 1, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("Scenario 1, State 2");
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Mixed_Int_Scenario_and_String_Scenario_and_String_State()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Mixed_String_Scenario_and_Int_State()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo("Next State")
|
||||
.RespondWith(Response.Create().WithBody("int state, Setting State 2"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("state string")
|
||||
.WillSetStateTo(1)
|
||||
.RespondWith(Response.Create().WithBody("string state, Setting State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("1")
|
||||
.WhenStateIs("Next State")
|
||||
.RespondWith(Response.Create().WithBody("string state, State 2"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("state string")
|
||||
.WhenStateIs(1)
|
||||
.RespondWith(Response.Create().WithBody("string state, State 2"));
|
||||
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("int state, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("string state, State 2");
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("string state, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("string state, State 2");
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_TodoList_Example()
|
||||
{
|
||||
// Assign
|
||||
var server = WireMockServer.Start();
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_Respect_Mixed_Int_Scenario_and_String_Scenario_and_String_State()
|
||||
{
|
||||
// given
|
||||
string path = $"/foo_{Guid.NewGuid()}";
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario("To do list")
|
||||
.WillSetStateTo("TodoList State Started")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk"));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario(1)
|
||||
.WillSetStateTo("Next State")
|
||||
.RespondWith(Response.Create().WithBody("int state, Setting State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingPost())
|
||||
.InScenario("To do list")
|
||||
.WhenStateIs("TodoList State Started")
|
||||
.WillSetStateTo("Cancel newspaper item added")
|
||||
.RespondWith(Response.Create().WithStatusCode(201));
|
||||
server
|
||||
.Given(Request.Create().WithPath(path).UsingGet())
|
||||
.InScenario("1")
|
||||
.WhenStateIs("Next State")
|
||||
.RespondWith(Response.Create().WithBody("string state, State 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario("To do list")
|
||||
.WhenStateIs("Cancel newspaper item added")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
|
||||
// when
|
||||
var responseIntScenario = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
var responseWithIntState = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + path).ConfigureAwait(false);
|
||||
|
||||
Check.That(server.Scenarios.Any()).IsFalse();
|
||||
// then
|
||||
Check.That(responseIntScenario).Equals("int state, Setting State 2");
|
||||
Check.That(responseWithIntState).Equals("string state, State 2");
|
||||
|
||||
// Act and Assert
|
||||
string url = "http://localhost:" + server.Ports[0];
|
||||
string getResponse1 = new HttpClient().GetStringAsync(url + "/todo/items").Result;
|
||||
Check.That(getResponse1).Equals("Buy milk");
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
|
||||
Check.That(server.Scenarios["To do list"].NextState).IsEqualTo("TodoList State Started");
|
||||
Check.That(server.Scenarios["To do list"].Started).IsTrue();
|
||||
Check.That(server.Scenarios["To do list"].Finished).IsFalse();
|
||||
[Fact]
|
||||
public async Task Scenarios_TodoList_Example()
|
||||
{
|
||||
// Arrange
|
||||
var server = WireMockServer.Start();
|
||||
var client = server.CreateClient();
|
||||
|
||||
var postResponse = await new HttpClient().PostAsync(url + "/todo/items", new StringContent("Cancel newspaper subscription")).ConfigureAwait(false);
|
||||
Check.That(postResponse.StatusCode).Equals(HttpStatusCode.Created);
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario("To do list")
|
||||
.WillSetStateTo("TodoList State Started")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk"));
|
||||
|
||||
Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
|
||||
Check.That(server.Scenarios["To do list"].NextState).IsEqualTo("Cancel newspaper item added");
|
||||
Check.That(server.Scenarios["To do list"].Started).IsTrue();
|
||||
Check.That(server.Scenarios["To do list"].Finished).IsFalse();
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingPost())
|
||||
.InScenario("To do list")
|
||||
.WhenStateIs("TodoList State Started")
|
||||
.WillSetStateTo("Cancel newspaper item added")
|
||||
.RespondWith(Response.Create().WithStatusCode(201));
|
||||
|
||||
string getResponse2 = await new HttpClient().GetStringAsync(url + "/todo/items").ConfigureAwait(false);
|
||||
Check.That(getResponse2).Equals("Buy milk;Cancel newspaper subscription");
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario("To do list")
|
||||
.WhenStateIs("Cancel newspaper item added")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
|
||||
|
||||
Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
|
||||
Check.That(server.Scenarios["To do list"].NextState).IsNull();
|
||||
Check.That(server.Scenarios["To do list"].Started).IsTrue();
|
||||
Check.That(server.Scenarios["To do list"].Finished).IsTrue();
|
||||
Check.That(server.Scenarios.Any()).IsFalse();
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
// Act and Assert
|
||||
var getResponse1 = await client.GetStringAsync("/todo/items").ConfigureAwait(false);
|
||||
Check.That(getResponse1).Equals("Buy milk");
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_process_request_if_equals_state_and_multiple_state_defined()
|
||||
{
|
||||
// Assign
|
||||
var server = WireMockServer.Start();
|
||||
Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
|
||||
Check.That(server.Scenarios["To do list"].NextState).IsEqualTo("TodoList State Started");
|
||||
Check.That(server.Scenarios["To do list"].Started).IsTrue();
|
||||
Check.That(server.Scenarios["To do list"].Finished).IsFalse();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/state1").UsingGet())
|
||||
.InScenario("s1")
|
||||
.WillSetStateTo("Test state 1")
|
||||
.RespondWith(Response.Create().WithBody("No state msg 1"));
|
||||
var postResponse = await client.PostAsync("/todo/items", new StringContent("Cancel newspaper subscription")).ConfigureAwait(false);
|
||||
Check.That(postResponse.StatusCode).Equals(HttpStatusCode.Created);
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo1X").UsingGet())
|
||||
.InScenario("s1")
|
||||
.WhenStateIs("Test state 1")
|
||||
.RespondWith(Response.Create().WithBody("Test state msg 1"));
|
||||
Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
|
||||
Check.That(server.Scenarios["To do list"].NextState).IsEqualTo("Cancel newspaper item added");
|
||||
Check.That(server.Scenarios["To do list"].Started).IsTrue();
|
||||
Check.That(server.Scenarios["To do list"].Finished).IsFalse();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/state2").UsingGet())
|
||||
.InScenario("s2")
|
||||
.WillSetStateTo("Test state 2")
|
||||
.RespondWith(Response.Create().WithBody("No state msg 2"));
|
||||
string getResponse2 = await client.GetStringAsync("/todo/items").ConfigureAwait(false);
|
||||
Check.That(getResponse2).Equals("Buy milk;Cancel newspaper subscription");
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo2X").UsingGet())
|
||||
.InScenario("s2")
|
||||
.WhenStateIs("Test state 2")
|
||||
.RespondWith(Response.Create().WithBody("Test state msg 2"));
|
||||
Check.That(server.Scenarios["To do list"].Name).IsEqualTo("To do list");
|
||||
Check.That(server.Scenarios["To do list"].NextState).IsNull();
|
||||
Check.That(server.Scenarios["To do list"].Started).IsTrue();
|
||||
Check.That(server.Scenarios["To do list"].Finished).IsTrue();
|
||||
|
||||
// Act and Assert
|
||||
string url = "http://localhost:" + server.Ports[0];
|
||||
var responseNoState1 = await new HttpClient().GetStringAsync(url + "/state1").ConfigureAwait(false);
|
||||
Check.That(responseNoState1).Equals("No state msg 1");
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
var responseNoState2 = await new HttpClient().GetStringAsync(url + "/state2").ConfigureAwait(false);
|
||||
Check.That(responseNoState2).Equals("No state msg 2");
|
||||
[Fact]
|
||||
public async Task Scenarios_TodoList_WithSetState()
|
||||
{
|
||||
// Arrange
|
||||
var scenario = "To do list";
|
||||
using var server = WireMockServer.Start();
|
||||
var client = server.CreateClient();
|
||||
|
||||
var responseWithState1 = await new HttpClient().GetStringAsync(url + "/foo1X").ConfigureAwait(false);
|
||||
Check.That(responseWithState1).Equals("Test state msg 1");
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WhenStateIs("Buy milk")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk"));
|
||||
|
||||
var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo2X").ConfigureAwait(false);
|
||||
Check.That(responseWithState2).Equals("Test state msg 2");
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WhenStateIs("Cancel newspaper")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
// Act and Assert
|
||||
server.SetScenarioState(scenario, "Buy milk");
|
||||
server.Scenarios[scenario].Should().BeEquivalentTo(new { Name = scenario, NextState = "Buy milk" });
|
||||
|
||||
var getResponse1 = await client.GetStringAsync("/todo/items").ConfigureAwait(false);
|
||||
getResponse1.Should().Be("Buy milk");
|
||||
|
||||
server.SetScenarioState(scenario, "Cancel newspaper");
|
||||
server.Scenarios[scenario].Name.Should().Be(scenario);
|
||||
server.Scenarios[scenario].Should().BeEquivalentTo(new { Name = scenario, NextState = "Cancel newspaper" });
|
||||
|
||||
var getResponse2 = await client.GetStringAsync("/todo/items").ConfigureAwait(false);
|
||||
getResponse2.Should().Be("Buy milk;Cancel newspaper subscription");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Scenarios_TodoList_WithSetStateToNull_ShouldThrowException()
|
||||
{
|
||||
// Arrange
|
||||
var scenario = "To do list";
|
||||
using var server = WireMockServer.Start();
|
||||
var client = server.CreateClient();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WhenStateIs("Buy milk")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/todo/items").UsingGet())
|
||||
.InScenario(scenario)
|
||||
.WhenStateIs("Cancel newspaper")
|
||||
.RespondWith(Response.Create().WithBody("Buy milk;Cancel newspaper subscription"));
|
||||
|
||||
// Act
|
||||
server.SetScenarioState(scenario, null);
|
||||
var action = async () => await client.GetStringAsync("/todo/items");
|
||||
|
||||
// Assert
|
||||
action.Should().ThrowAsync<HttpRequestException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Scenarios_Should_process_request_if_equals_state_and_multiple_state_defined()
|
||||
{
|
||||
// Assign
|
||||
var server = WireMockServer.Start();
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/state1").UsingGet())
|
||||
.InScenario("s1")
|
||||
.WillSetStateTo("Test state 1")
|
||||
.RespondWith(Response.Create().WithBody("No state msg 1"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo1X").UsingGet())
|
||||
.InScenario("s1")
|
||||
.WhenStateIs("Test state 1")
|
||||
.RespondWith(Response.Create().WithBody("Test state msg 1"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/state2").UsingGet())
|
||||
.InScenario("s2")
|
||||
.WillSetStateTo("Test state 2")
|
||||
.RespondWith(Response.Create().WithBody("No state msg 2"));
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/foo2X").UsingGet())
|
||||
.InScenario("s2")
|
||||
.WhenStateIs("Test state 2")
|
||||
.RespondWith(Response.Create().WithBody("Test state msg 2"));
|
||||
|
||||
// Act and Assert
|
||||
string url = "http://localhost:" + server.Ports[0];
|
||||
var responseNoState1 = await new HttpClient().GetStringAsync(url + "/state1").ConfigureAwait(false);
|
||||
Check.That(responseNoState1).Equals("No state msg 1");
|
||||
|
||||
var responseNoState2 = await new HttpClient().GetStringAsync(url + "/state2").ConfigureAwait(false);
|
||||
Check.That(responseNoState2).Equals("No state msg 2");
|
||||
|
||||
var responseWithState1 = await new HttpClient().GetStringAsync(url + "/foo1X").ConfigureAwait(false);
|
||||
Check.That(responseWithState1).Equals("Test state msg 1");
|
||||
|
||||
var responseWithState2 = await new HttpClient().GetStringAsync(url + "/foo2X").ConfigureAwait(false);
|
||||
Check.That(responseWithState2).Equals("Test state msg 2");
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,6 @@ public partial class TestcontainersTests
|
||||
var adminUsername = $"username_{Guid.NewGuid()}";
|
||||
var adminPassword = $"password_{Guid.NewGuid()}";
|
||||
var wireMockContainer = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.WithAdminUserNameAndPassword(adminUsername, adminPassword)
|
||||
.WithCommand("--UseHttp2")
|
||||
.WithCommand("--Urls", "http://*:80 grpc://*:9090")
|
||||
@@ -69,7 +67,7 @@ public partial class TestcontainersTests
|
||||
}
|
||||
finally
|
||||
{
|
||||
await wireMockContainer.StopAsync();
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,8 +78,6 @@ public partial class TestcontainersTests
|
||||
var adminUsername = $"username_{Guid.NewGuid()}";
|
||||
var adminPassword = $"password_{Guid.NewGuid()}";
|
||||
var wireMockContainer = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.WithAdminUserNameAndPassword(adminUsername, adminPassword)
|
||||
.AddUrl("http://*:8080")
|
||||
.AddUrl("grpc://*:9090")
|
||||
@@ -121,7 +117,7 @@ public partial class TestcontainersTests
|
||||
}
|
||||
finally
|
||||
{
|
||||
await wireMockContainer.StopAsync();
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +132,7 @@ public partial class TestcontainersTests
|
||||
|
||||
Then_ReplyMessage_Should_BeCorrect(reply);
|
||||
|
||||
await wireMockContainer.StopAsync();
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -150,14 +146,12 @@ public partial class TestcontainersTests
|
||||
|
||||
Then_ReplyMessage_Should_BeCorrect(reply);
|
||||
|
||||
await wireMockContainer.StopAsync();
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
|
||||
private static async Task<WireMockContainer> Given_WireMockContainerIsStartedForHttpAndGrpcAsync()
|
||||
{
|
||||
var wireMockContainer = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.AddUrl("grpc://*:9090")
|
||||
.Build();
|
||||
|
||||
@@ -169,8 +163,6 @@ public partial class TestcontainersTests
|
||||
private static async Task<WireMockContainer> Given_WireMockContainerWithProtoDefinitionAtServerLevelIsStartedForHttpAndGrpcAsync()
|
||||
{
|
||||
var wireMockContainer = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.AddUrl("grpc://*:9090")
|
||||
.AddProtoDefinition("my-greeter", ReadFile("greet.proto"))
|
||||
.Build();
|
||||
|
||||
@@ -11,10 +11,11 @@ using WireMock.Net.Testcontainers;
|
||||
using WireMock.Net.Testcontainers.Utils;
|
||||
using WireMock.Net.Tests.Facts;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace WireMock.Net.Tests.Testcontainers;
|
||||
|
||||
public partial class TestcontainersTests
|
||||
public partial class TestcontainersTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
[Fact]
|
||||
public async Task WireMockContainer_Build_And_StartAsync_and_StopAsync()
|
||||
@@ -23,12 +24,11 @@ public partial class TestcontainersTests
|
||||
var adminUsername = $"username_{Guid.NewGuid()}";
|
||||
var adminPassword = $"password_{Guid.NewGuid()}";
|
||||
var wireMockContainer = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.WithAdminUserNameAndPassword(adminUsername, adminPassword)
|
||||
.Build();
|
||||
|
||||
await StartTestAndStopAsync(wireMockContainer);
|
||||
await StartTestAsync(wireMockContainer);
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
|
||||
// https://github.com/testcontainers/testcontainers-dotnet/issues/1322
|
||||
@@ -38,17 +38,15 @@ public partial class TestcontainersTests
|
||||
// Act
|
||||
var dummyNetwork = new NetworkBuilder()
|
||||
.WithName("Dummy Network for TestcontainersTests")
|
||||
.WithCleanUp(true)
|
||||
.Build();
|
||||
|
||||
var wireMockContainer = new WireMockContainerBuilder()
|
||||
.WithNetwork(dummyNetwork)
|
||||
.WithWatchStaticMappings(true)
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.Build();
|
||||
|
||||
await StartTestAndStopAsync(wireMockContainer);
|
||||
await StartTestAsync(wireMockContainer);
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -58,8 +56,6 @@ public partial class TestcontainersTests
|
||||
var adminUsername = $"username_{Guid.NewGuid()}";
|
||||
var adminPassword = $"password_{Guid.NewGuid()}";
|
||||
var wireMockContainerBuilder = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.WithAdminUserNameAndPassword(adminUsername, adminPassword);
|
||||
|
||||
var imageOS = await TestcontainersUtils.GetImageOSAsync.Value;
|
||||
@@ -74,7 +70,8 @@ public partial class TestcontainersTests
|
||||
|
||||
var wireMockContainer = wireMockContainerBuilder.Build();
|
||||
|
||||
await StartTestAndStopAsync(wireMockContainer);
|
||||
await StartTestAsync(wireMockContainer);
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -84,8 +81,6 @@ public partial class TestcontainersTests
|
||||
var adminUsername = $"username_{Guid.NewGuid()}";
|
||||
var adminPassword = $"password_{Guid.NewGuid()}";
|
||||
var wireMockContainerBuilder = new WireMockContainerBuilder()
|
||||
.WithAutoRemove(true)
|
||||
.WithCleanUp(true)
|
||||
.WithAdminUserNameAndPassword(adminUsername, adminPassword);
|
||||
|
||||
var imageOS = await TestcontainersUtils.GetImageOSAsync.Value;
|
||||
@@ -100,31 +95,48 @@ public partial class TestcontainersTests
|
||||
|
||||
var wireMockContainer = wireMockContainerBuilder.Build();
|
||||
|
||||
await StartTestAndStopAsync(wireMockContainer);
|
||||
await StartTestAsync(wireMockContainer);
|
||||
await StopAsync(wireMockContainer);
|
||||
}
|
||||
|
||||
private static async Task StartTestAndStopAsync(WireMockContainer wireMockContainer)
|
||||
private static async Task StartTestAsync(WireMockContainer wireMockContainer)
|
||||
{
|
||||
// Start
|
||||
await wireMockContainer.StartAsync().ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
using (new AssertionScope())
|
||||
{
|
||||
var url = wireMockContainer.GetPublicUrl();
|
||||
url.Should().NotBeNullOrWhiteSpace();
|
||||
|
||||
var adminClient = wireMockContainer.CreateWireMockAdminClient();
|
||||
|
||||
var settings = await adminClient.GetSettingsAsync();
|
||||
settings.Should().NotBeNull();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StopAsync(WireMockContainer wireMockContainer)
|
||||
{
|
||||
try
|
||||
{
|
||||
await wireMockContainer.StartAsync().ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
using (new AssertionScope())
|
||||
{
|
||||
var url = wireMockContainer.GetPublicUrl();
|
||||
url.Should().NotBeNullOrWhiteSpace();
|
||||
|
||||
var adminClient = wireMockContainer.CreateWireMockAdminClient();
|
||||
|
||||
var settings = await adminClient.GetSettingsAsync();
|
||||
settings.Should().NotBeNull();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
await wireMockContainer.StopAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Sometimes we get this exception, so for now ignore it.
|
||||
/*
|
||||
Failed WireMock.Net.Tests.Testcontainers.TestcontainersTests.WireMockContainer_Build_WithImageAsText_And_StartAsync_and_StopAsync [9 s]
|
||||
Error Message:
|
||||
System.NullReferenceException : Object reference not set to an instance of an object.
|
||||
Stack Trace:
|
||||
at DotNet.Testcontainers.Containers.DockerContainer.UnsafeStopAsync(CancellationToken ct) in /_/src/Testcontainers/Containers/DockerContainer.cs:line 567
|
||||
at DotNet.Testcontainers.Containers.DockerContainer.StopAsync(CancellationToken ct) in /_/src/Testcontainers/Containers/DockerContainer.cs:line 319
|
||||
*/
|
||||
|
||||
testOutputHelper.WriteLine($"Exception during StopAsync: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using AnyOfTypes;
|
||||
using FluentAssertions;
|
||||
using WireMock.Matchers;
|
||||
@@ -57,12 +58,22 @@ public class TypeLoaderTests
|
||||
[Fact]
|
||||
public void LoadNewInstance()
|
||||
{
|
||||
// Act
|
||||
AnyOf<string, StringPattern> pattern = "x";
|
||||
var result = TypeLoader.LoadNewInstance<ICSharpCodeMatcher>(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, pattern);
|
||||
var current = Directory.GetCurrentDirectory();
|
||||
try
|
||||
{
|
||||
Directory.SetCurrentDirectory(Path.GetTempPath());
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
// Act
|
||||
AnyOf<string, StringPattern> pattern = "x";
|
||||
var result = TypeLoader.LoadNewInstance<ICSharpCodeMatcher>(MatchBehaviour.AcceptOnMatch, MatchOperator.Or, pattern);
|
||||
|
||||
// Assert
|
||||
result.Should().NotBeNull();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Directory.SetCurrentDirectory(current);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'net452'">
|
||||
<PackageReference Include="System.Net.Http.Json" Version="3.2.1" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="8.0.1" />
|
||||
<PackageReference Include="JsonConverter.System.Text.Json" Version="0.7.0" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.25.1" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="2.60.0" />
|
||||
|
||||
@@ -560,6 +560,30 @@ public class WireMockServerAdminTests
|
||||
Check.That(await response.Content.ReadAsStringAsync().ConfigureAwait(false)).Equals($"{{\"Status\":\"Mappings deleted. Affected GUIDs: [{guid1}, {guid2}]\"}}");
|
||||
}
|
||||
|
||||
#if NET5_0_OR_GREATER
|
||||
[Fact]
|
||||
public async Task WireMockServer_CreateHttpClientFactory_And_CallEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var server = WireMockServer.Start();
|
||||
var factory = server.CreateHttpClientFactory();
|
||||
var client = factory.CreateClient("any name");
|
||||
|
||||
// Act
|
||||
await client.GetAsync($"{server.Url}/foo").ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
Check.That(server.LogEntries).HasSize(1);
|
||||
var requestLogged = server.LogEntries.First();
|
||||
Check.That(requestLogged.RequestMessage.Method).IsEqualTo("GET");
|
||||
Check.That(requestLogged.RequestMessage.BodyData).IsNull();
|
||||
|
||||
// Cleanup
|
||||
server.Stop();
|
||||
server.Dispose();
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_CreateClient_And_CallEndpoint()
|
||||
{
|
||||
|
||||
@@ -924,49 +924,4 @@ public class WireMockServerProxyTests
|
||||
server.LogEntries.Should().HaveCount(1);
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_ProxyAndRecordSettings_SameRequest_ShouldProxyAll()
|
||||
{
|
||||
//Arrange
|
||||
var wireMockServerSettings = new WireMockServerSettings
|
||||
{
|
||||
Urls = new[] { "http://localhost:19091" },
|
||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||
{
|
||||
Url = "http://postman-echo.com",
|
||||
SaveMapping = true,
|
||||
ProxyAll = true,
|
||||
SaveMappingToFile = false,
|
||||
ExcludedHeaders = new[] { "Postman-Token" },
|
||||
ExcludedCookies = new[] { "sails.sid" }
|
||||
}
|
||||
};
|
||||
|
||||
var server = WireMockServer.Start(wireMockServerSettings);
|
||||
|
||||
var requestBody = "{\"key1\": \"value1\", \"key2\": \"value2\"}";
|
||||
var request = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
RequestUri = new Uri("http://localhost:19091/post"),
|
||||
Content = new StringContent(requestBody)
|
||||
};
|
||||
var request2 = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Post,
|
||||
RequestUri = new Uri("http://localhost:19091/post"),
|
||||
Content = new StringContent(requestBody)
|
||||
};
|
||||
server.ResetMappings();
|
||||
|
||||
//Act
|
||||
await new HttpClient().SendAsync(request);
|
||||
await new HttpClient().SendAsync(request2);
|
||||
|
||||
//Assert
|
||||
Check.That(server.Mappings.Count()).IsEqualTo(3);
|
||||
|
||||
server.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using Xunit;
|
||||
|
||||
@@ -44,6 +43,78 @@ public partial class WireMockServerTests
|
||||
response.Should().Contain("Hello, Stef!");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithTransformer_WithJsonBodyAsArray_ShouldWork()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.Start();
|
||||
server
|
||||
.WhenRequest(req => req
|
||||
.WithPath("/withbody")
|
||||
.UsingPost()
|
||||
)
|
||||
.ThenRespondWith(rsp => rsp
|
||||
.WithSuccess()
|
||||
.WithBodyAsJson(new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
test = "test",
|
||||
secret = true
|
||||
},
|
||||
new
|
||||
{
|
||||
test = "123",
|
||||
secret = false
|
||||
}
|
||||
}
|
||||
)
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
// Act
|
||||
var response = await GetResponseAsync(server, "/withbody");
|
||||
|
||||
// Assert
|
||||
response.Should().Be("""[{"test":"test","secret":true},{"test":"123","secret":false}]""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithTransformer_WithJsonBodyAsList_ShouldWork()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.Start();
|
||||
server
|
||||
.WhenRequest(req => req
|
||||
.WithPath("/withbody")
|
||||
.UsingPost()
|
||||
)
|
||||
.ThenRespondWith(rsp => rsp
|
||||
.WithSuccess()
|
||||
.WithBodyAsJson(
|
||||
new List<object>
|
||||
{
|
||||
new
|
||||
{
|
||||
test = "test",
|
||||
secret = true
|
||||
},
|
||||
new
|
||||
{
|
||||
test = "123",
|
||||
secret = false
|
||||
}
|
||||
})
|
||||
.WithTransformer()
|
||||
);
|
||||
|
||||
// Act
|
||||
var response = await GetResponseAsync(server, "/withbody");
|
||||
|
||||
// Assert
|
||||
response.Should().Be("""[{"test":"test","secret":true},{"test":"123","secret":false}]""");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithTransformerBefore_WithBodyFromFile_ShouldWork()
|
||||
{
|
||||
@@ -88,8 +159,7 @@ public partial class WireMockServerTests
|
||||
|
||||
private static async Task<string> GetResponseAsync(WireMockServer server, string relativePath)
|
||||
{
|
||||
using HttpClient httpClient = new HttpClient();
|
||||
httpClient.BaseAddress = new Uri(server.Urls[0]);
|
||||
using var httpClient = server.CreateClient();
|
||||
|
||||
using var requestContent = new StringContent(RequestXml);
|
||||
using var responseMsg = await httpClient.PostAsync(relativePath, requestContent);
|
||||
|
||||