mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-13 05:50:36 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f89f0fa466 | ||
|
|
b892e85d2a | ||
|
|
836976ca19 | ||
|
|
c845f73dd0 | ||
|
|
2cbbef01ae | ||
|
|
dd80fd7822 | ||
|
|
527278e60c | ||
|
|
7d7f1f8fbb | ||
|
|
af124d556d | ||
|
|
60931f6273 | ||
|
|
b99a80e782 | ||
|
|
07c9aebf44 |
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -20,7 +20,9 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Execute Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
run: |
|
||||
dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
linux-build-and-run:
|
||||
name: Run Tests on Linux
|
||||
@@ -33,7 +35,9 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 'Execute Tests'
|
||||
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
run: |
|
||||
dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
|
||||
dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
|
||||
|
||||
- name: Install .NET Aspire workload
|
||||
run: dotnet workload install aspire
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,3 +1,26 @@
|
||||
# 1.6.4 (25 September 2024)
|
||||
- [#1169](https://github.com/WireMock-Net/WireMock.Net/pull/1169) - Allow mapping without Path or Url [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1170](https://github.com/WireMock-Net/WireMock.Net/pull/1170) - Update the .NET Aspire tests [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1172](https://github.com/WireMock-Net/WireMock.Net/pull/1172) - Fix JSON parsing of text/plain content type [bug] contributed by [ruxo](https://github.com/ruxo)
|
||||
- [#1177](https://github.com/WireMock-Net/WireMock.Net/pull/1177) - Unpin Testcontainers version and upgrade to version 3.10.0 [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1178](https://github.com/WireMock-Net/WireMock.Net/pull/1178) - Upgrade CS-Script to version 4.8.17 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1179](https://github.com/WireMock-Net/WireMock.Net/pull/1179) - Add WireMock.Net.TUnit project [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1146](https://github.com/WireMock-Net/WireMock.Net/issues/1146) - Bump Request CS-Script 4.8.13 to 4.8.17 [feature]
|
||||
- [#1167](https://github.com/WireMock-Net/WireMock.Net/issues/1167) - Admin API fails to create a mapping with Request Header matching using WildCardMatcher [bug]
|
||||
- [#1168](https://github.com/WireMock-Net/WireMock.Net/issues/1168) - Numbers in text/plain content is parsed as JSON. [bug]
|
||||
- [#1176](https://github.com/WireMock-Net/WireMock.Net/issues/1176) - WireMock.NET TestContainer Dependency Constraint Issue [bug]
|
||||
|
||||
# 1.6.3 (07 September 2024)
|
||||
- [#1165](https://github.com/WireMock-Net/WireMock.Net/pull/1165) - Fix listen on AnyIP for url 0.0.0.0 contributed by [cocoon](https://github.com/cocoon)
|
||||
- [#1154](https://github.com/WireMock-Net/WireMock.Net/issues/1154) - Listen on all ips [bug]
|
||||
|
||||
# 1.6.2 (04 September 2024)
|
||||
- [#1152](https://github.com/WireMock-Net/WireMock.Net/pull/1152) - Update MappingConverter to correctly write the Matcher as C# code [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1163](https://github.com/WireMock-Net/WireMock.Net/pull/1163) - Upgrade Aspire to version 8.2.0 [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1166](https://github.com/WireMock-Net/WireMock.Net/pull/1166) - Also update IWireMockMiddlewareOptions when settings are updated via admin interface [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1151](https://github.com/WireMock-Net/WireMock.Net/issues/1151) - MappingsToCSharpCode should use RegexMatcher when specified [bug]
|
||||
- [#1164](https://github.com/WireMock-Net/WireMock.Net/issues/1164) - WithParam not working. [bug]
|
||||
|
||||
# 1.6.1 (22 August 2024)
|
||||
- [#1160](https://github.com/WireMock-Net/WireMock.Net/pull/1160) - Use default timeout for Regex [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1159](https://github.com/WireMock-Net/WireMock.Net/issues/1159) - RegexMatchTimeoutException when trying to parse HTTP version [bug]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.6.1</VersionPrefix>
|
||||
<VersionPrefix>1.6.4</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
@@ -44,12 +44,12 @@
|
||||
</Choose>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.29.0.95321">
|
||||
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.32.0.97167">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=1.6.1
|
||||
SET version=1.6.4
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# 1.6.1 (22 August 2024)
|
||||
- #1160 Use default timeout for Regex [bug]
|
||||
- #1159 RegexMatchTimeoutException when trying to parse HTTP version [bug]
|
||||
# 1.6.4 (25 September 2024)
|
||||
- #1169 Allow mapping without Path or Url [bug]
|
||||
- #1170 Update the .NET Aspire tests [feature]
|
||||
- #1172 Fix JSON parsing of text/plain content type [bug]
|
||||
- #1177 Unpin Testcontainers version and upgrade to version 3.10.0 [bug]
|
||||
- #1178 Upgrade CS-Script to version 4.8.17 [feature]
|
||||
- #1179 Add WireMock.Net.TUnit project [feature]
|
||||
- #1146 Bump Request CS-Script 4.8.13 to 4.8.17 [feature]
|
||||
- #1167 Admin API fails to create a mapping with Request Header matching using WildCardMatcher [bug]
|
||||
- #1168 Numbers in text/plain content is parsed as JSON. [bug]
|
||||
- #1176 WireMock.NET TestContainer Dependency Constraint Issue [bug]
|
||||
|
||||
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
||||
20
README.md
20
README.md
@@ -39,16 +39,16 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
|
||||
|
||||
| | Official | Preview [:information_source:](https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions) |
|
||||
| - | - | - |
|
||||
| **WireMock.Net** | [](https://www.nuget.org/packages/WireMock.Net) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
|
||||
| **WireMock.Net.StandAlone** | [](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
|
||||
| **WireMock.Net.FluentAssertions** | [](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
||||
| **WireMock.Net.Testcontainers** | [](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
|
||||
| **WireMock.Net.Aspire** | [](https://www.nuget.org/packages/WireMock.Net.Aspire) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire)
|
||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||
| **WireMock.Net** | [](https://www.nuget.org/packages/WireMock.Net) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
|
||||
| **WireMock.Net.StandAlone** | [](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
|
||||
| **WireMock.Net.FluentAssertions** | [](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Net.xUnit** | [](https://www.nuget.org/packages/WireMock.Net.xUnit) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
|
||||
| **WireMock.Net.Testcontainers** | [](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
|
||||
| **WireMock.Net.Aspire** | [](https://www.nuget.org/packages/WireMock.Net.Aspire) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire)
|
||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||
|
||||
|
||||
## :memo: Development
|
||||
|
||||
@@ -131,6 +131,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Aspire.TestApp
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspireApp1.AppHostOriginal", "examples-Aspire\AspireApp1.AppHostOriginal\AspireApp1.AppHostOriginal.csproj", "{C9210DA3-F390-4598-8512-349A473FE9C9}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.TUnit", "src\WireMock.Net.TUnit\WireMock.Net.TUnit.csproj", "{91024A93-848F-4A02-AF53-5EBE5834E23C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TUnitTests", "test\WireMock.Net.TUnitTests\WireMock.Net.TUnitTests.csproj", "{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -317,6 +321,14 @@ Global
|
||||
{C9210DA3-F390-4598-8512-349A473FE9C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C9210DA3-F390-4598-8512-349A473FE9C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C9210DA3-F390-4598-8512-349A473FE9C9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{91024A93-848F-4A02-AF53-5EBE5834E23C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -369,6 +381,8 @@ Global
|
||||
{CE602F57-FEF8-4559-A9E0-6200BE1BF398} = {0BB8B634-407A-4610-A91F-11586990767A}
|
||||
{F1B5999D-D22E-48A6-AB86-18A7876BD32E} = {0BB8B634-407A-4610-A91F-11586990767A}
|
||||
{C9210DA3-F390-4598-8512-349A473FE9C9} = {AD474543-0715-49F2-A284-936B060BF736}
|
||||
{91024A93-848F-4A02-AF53-5EBE5834E23C} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{4CD237F7-B616-46B8-872F-E49B4BBB3EAE} = {0BB8B634-407A-4610-A91F-11586990767A}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
# See: https://docs.sonarsource.com/sonarcloud/enriching/test-coverage/dotnet-test-coverage
|
||||
- script: |
|
||||
dotnet sonarscanner begin /k:"WireMock-Net_WireMock.Net" /o:"wiremock-net" /d:sonar.branch.name=$(Build.SourceBranchName) /d:sonar.host.url="https://sonarcloud.io" /d:sonar.token="$(SONAR_TOKEN)" /d:sonar.pullrequest.provider=github /d:sonar.dotnet.excludeTestProjects=true /d:sonar.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
|
||||
dotnet sonarscanner begin /k:"WireMock-Net_WireMock.Net" /o:"wiremock-net" /d:sonar.branch.name=$(Build.SourceBranchName) /d:sonar.host.url="https://sonarcloud.io" /d:sonar.token="$(SONAR_TOKEN)" /d:sonar.pullrequest.provider=github /d:sonar.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
|
||||
displayName: 'Begin analysis on SonarCloud'
|
||||
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
|
||||
|
||||
@@ -52,13 +52,14 @@ jobs:
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-1.xml"
|
||||
displayName: 'Execute WireMock.Net.Tests with Coverage'
|
||||
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-xunit.xml"
|
||||
dotnet-coverage collect "dotnet test ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-tunit.xml"
|
||||
displayName: 'Execute WireMock.Net.Tests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
inputs:
|
||||
script: |
|
||||
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-2.xml"
|
||||
dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-aspire.xml"
|
||||
displayName: 'Execute WireMock.Net.Aspire.Tests with Coverage'
|
||||
|
||||
- task: CmdLine@2
|
||||
|
||||
25
src/WireMock.Net.Abstractions/Models/IBodyDataExtensions.cs
Normal file
25
src/WireMock.Net.Abstractions/Models/IBodyDataExtensions.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Types;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace WireMock.Util;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public static class IBodyDataExtensions
|
||||
{
|
||||
public static BodyType GetBodyType(this IBodyData bodyData)
|
||||
{
|
||||
if (bodyData.DetectedBodyTypeFromContentType is not null and not BodyType.None)
|
||||
{
|
||||
return bodyData.DetectedBodyTypeFromContentType.Value;
|
||||
}
|
||||
|
||||
if (bodyData.DetectedBodyType is not null and not BodyType.None)
|
||||
{
|
||||
return bodyData.DetectedBodyType.Value;
|
||||
}
|
||||
|
||||
return BodyType.None;
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' or '$(TargetFramework)' == 'netcoreapp3.1' or '$(TargetFramework)' == 'net5.0' or '$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net7.0' or '$(TargetFramework)' == 'net8.0'">
|
||||
<PackageReference Include="CS-Script" Version="4.8.13" />
|
||||
<PackageReference Include="CS-Script" Version="4.8.17" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
80
src/WireMock.Net.TUnit/TUnitWireMockLogger.cs
Normal file
80
src/WireMock.Net.TUnit/TUnitWireMockLogger.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using TUnit.Core.Logging;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.Logging;
|
||||
|
||||
namespace WireMock.Net.TUnit;
|
||||
|
||||
/// <summary>
|
||||
/// When using TUnit, this class enables to log the output from WireMock.Net to the <see cref="TUnitLogger"/>.
|
||||
/// </summary>
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public sealed class TUnitWireMockLogger : IWireMockLogger
|
||||
{
|
||||
private readonly TUnitLogger _tUnitLogger;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance on the <see cref="TUnitWireMockLogger"/>.
|
||||
/// </summary>
|
||||
/// <param name="tUnitLogger">Represents a class which can be used to provide test output.</param>
|
||||
public TUnitWireMockLogger(TUnitLogger tUnitLogger)
|
||||
{
|
||||
_tUnitLogger = Guard.NotNull(tUnitLogger);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Debug(string formatString, params object[] args)
|
||||
{
|
||||
_tUnitLogger.LogDebug(Format("Debug", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Info(string formatString, params object[] args)
|
||||
{
|
||||
_tUnitLogger.LogInformation(Format("Info", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Warn(string formatString, params object[] args)
|
||||
{
|
||||
_tUnitLogger.LogWarning(Format("Warning", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Error(string formatString, params object[] args)
|
||||
{
|
||||
_tUnitLogger.LogError(Format("Error", formatString, args));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Error(string formatString, Exception exception)
|
||||
{
|
||||
_tUnitLogger.LogError(Format("Error", formatString, exception.Message), exception);
|
||||
|
||||
if (exception is AggregateException ae)
|
||||
{
|
||||
ae.Handle(ex =>
|
||||
{
|
||||
_tUnitLogger.LogError(Format("Error", "Exception {0}", ex.Message), exception);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
|
||||
{
|
||||
var message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
|
||||
_tUnitLogger.LogDebug(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
|
||||
}
|
||||
|
||||
private static string Format(string level, string formatString, params object[] args)
|
||||
{
|
||||
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
|
||||
return $"{DateTime.UtcNow} [{level}] : {message}";
|
||||
}
|
||||
}
|
||||
38
src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj
Normal file
38
src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj
Normal file
@@ -0,0 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Some extensions for TUnit (TUnitLogger)</Description>
|
||||
<AssemblyTitle>WireMock.Net.TUnit</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Net.TUnit</AssemblyName>
|
||||
<RootNamespace>WireMock.Net.Tunit</RootNamespace>
|
||||
<PackageId>WireMock.Net.TUnit</PackageId>
|
||||
<PackageTags>tdd;wiremock;test;unittest;TUnit</PackageTags>
|
||||
<ProjectGuid>{0DE0954F-8C00-4E8D-B94A-4361FC1CB34A}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
||||
<PackageReference Include="TUnit.Core" Version="0.1.817" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -28,7 +28,7 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Stef.Validation" Version="0.1.1" />
|
||||
<PackageReference Include="Testcontainers" Version="[3.9.0]" />
|
||||
<PackageReference Include="Testcontainers" Version="3.10.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -73,8 +73,6 @@ public sealed class TestOutputHelperWireMockLogger : IWireMockLogger
|
||||
|
||||
private static string Format(string level, string formatString, params object[] args)
|
||||
{
|
||||
Guard.NotNull(formatString);
|
||||
|
||||
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
|
||||
return $"{DateTime.UtcNow} [{level}] : {message}";
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using WireMock.Constants;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Http;
|
||||
|
||||
@@ -33,12 +34,14 @@ internal static class HttpRequestMessageHelper
|
||||
MediaTypeHeaderValue.TryParse(value, out contentType);
|
||||
}
|
||||
|
||||
httpRequestMessage.Content = requestMessage.BodyData?.DetectedBodyType switch
|
||||
var bodyData = requestMessage.BodyData;
|
||||
httpRequestMessage.Content = bodyData?.GetBodyType() switch
|
||||
{
|
||||
BodyType.Bytes => ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType),
|
||||
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType),
|
||||
BodyType.String => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
|
||||
BodyType.FormUrlEncoded => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
|
||||
BodyType.Bytes => ByteArrayContentHelper.Create(bodyData!.BodyAsBytes!, contentType),
|
||||
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(bodyData!.BodyAsJson), contentType),
|
||||
BodyType.String => StringContentHelper.Create(bodyData!.BodyAsString!, contentType),
|
||||
BodyType.FormUrlEncoded => StringContentHelper.Create(bodyData!.BodyAsString!, contentType),
|
||||
|
||||
_ => httpRequestMessage.Content
|
||||
};
|
||||
|
||||
|
||||
@@ -75,8 +75,15 @@ namespace WireMock.Owin
|
||||
|
||||
private static void Listen(KestrelServerOptions kestrelOptions, HostUrlDetails urlDetail, Action<ListenOptions> configure)
|
||||
{
|
||||
// Listens on any IP with the given port.
|
||||
if (urlDetail is { Port: > 0, Host: "0.0.0.0" })
|
||||
{
|
||||
kestrelOptions.ListenAnyIP(urlDetail.Port, configure);
|
||||
return;
|
||||
}
|
||||
|
||||
// Listens on ::1 and 127.0.0.1 with the given port.
|
||||
if (urlDetail is { Port: > 0, Host: "localhost" or "127.0.0.1" or "0.0.0.0" or "::1" })
|
||||
if (urlDetail is { Port: > 0, Host: "localhost" or "127.0.0.1" or "::1" })
|
||||
{
|
||||
kestrelOptions.ListenLocalhost(urlDetail.Port, configure);
|
||||
return;
|
||||
@@ -113,4 +120,4 @@ namespace WireMock.Owin
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -136,30 +136,37 @@ namespace WireMock.Owin.Mappers
|
||||
return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage;
|
||||
}
|
||||
|
||||
private async Task<byte[]?> GetNormalBodyAsync(IResponseMessage responseMessage)
|
||||
{
|
||||
switch (responseMessage.BodyData?.DetectedBodyType)
|
||||
private async Task<byte[]?> GetNormalBodyAsync(IResponseMessage responseMessage) {
|
||||
var bodyData = responseMessage.BodyData;
|
||||
switch (bodyData?.GetBodyType())
|
||||
{
|
||||
case BodyType.String:
|
||||
case BodyType.FormUrlEncoded:
|
||||
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString!);
|
||||
return (bodyData.Encoding ?? _utf8NoBom).GetBytes(bodyData.BodyAsString!);
|
||||
|
||||
case BodyType.Json:
|
||||
var formatting = responseMessage.BodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
||||
var jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||
var formatting = bodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
||||
var jsonBody = JsonConvert.SerializeObject(bodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
return (bodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||
|
||||
#if PROTOBUF
|
||||
case BodyType.ProtoBuf:
|
||||
var protoDefinition = responseMessage.BodyData.ProtoDefinition?.Invoke().Text;
|
||||
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinition, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson).ConfigureAwait(false);
|
||||
var protoDefinition = bodyData.ProtoDefinition?.Invoke().Text;
|
||||
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinition, bodyData.ProtoBufMessageType, bodyData.BodyAsJson).ConfigureAwait(false);
|
||||
#endif
|
||||
|
||||
case BodyType.Bytes:
|
||||
return responseMessage.BodyData.BodyAsBytes;
|
||||
return bodyData.BodyAsBytes;
|
||||
|
||||
case BodyType.File:
|
||||
return _options.FileSystemHandler?.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile!);
|
||||
return _options.FileSystemHandler?.ReadResponseBodyAsFile(bodyData.BodyAsFile!);
|
||||
|
||||
case BodyType.MultiPart:
|
||||
_options.Logger.Warn("MultiPart body type is not handled!");
|
||||
break;
|
||||
|
||||
case BodyType.None:
|
||||
break;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -171,10 +178,7 @@ namespace WireMock.Owin.Mappers
|
||||
AppendResponseHeader(
|
||||
response,
|
||||
HttpKnownHeaderNames.Date,
|
||||
new[]
|
||||
{
|
||||
DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture)
|
||||
}
|
||||
[ DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture) ]
|
||||
);
|
||||
|
||||
// Set other headers
|
||||
|
||||
@@ -623,7 +623,7 @@ public partial class WireMockServer
|
||||
{
|
||||
var requestModel = DeserializeObject<RequestModel>(requestMessage);
|
||||
|
||||
var request = (Request)InitRequestBuilder(requestModel, false)!;
|
||||
var request = (Request)InitRequestBuilder(requestModel);
|
||||
|
||||
var dict = new Dictionary<ILogEntry, RequestMatchResult>();
|
||||
foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))
|
||||
|
||||
@@ -36,17 +36,13 @@ public partial class WireMockServer
|
||||
}
|
||||
}
|
||||
|
||||
private Guid? ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string? path = null)
|
||||
private Guid ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingModel, Guid? guid = null, string? path = null)
|
||||
{
|
||||
Guard.NotNull(mappingModel);
|
||||
Guard.NotNull(mappingModel.Request);
|
||||
Guard.NotNull(mappingModel.Response);
|
||||
|
||||
var requestBuilder = InitRequestBuilder(mappingModel.Request, true);
|
||||
if (requestBuilder == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var requestBuilder = InitRequestBuilder(mappingModel.Request);
|
||||
|
||||
var respondProvider = Given(requestBuilder, mappingModel.SaveToFile == true);
|
||||
|
||||
@@ -126,9 +122,9 @@ public partial class WireMockServer
|
||||
return respondProvider.Guid;
|
||||
}
|
||||
|
||||
private IRequestBuilder? InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
|
||||
private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
|
||||
{
|
||||
IRequestBuilder requestBuilder = Request.Create();
|
||||
var requestBuilder = Request.Create();
|
||||
|
||||
if (requestModel.ClientIP != null)
|
||||
{
|
||||
@@ -146,13 +142,11 @@ public partial class WireMockServer
|
||||
}
|
||||
}
|
||||
|
||||
bool pathOrUrlMatchersValid = false;
|
||||
if (requestModel.Path != null)
|
||||
{
|
||||
if (requestModel.Path is string path)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithPath(path);
|
||||
pathOrUrlMatchersValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -161,7 +155,6 @@ public partial class WireMockServer
|
||||
{
|
||||
var matchOperator = StringUtils.ParseMatchOperator(pathModel.MatchOperator);
|
||||
requestBuilder = requestBuilder.WithPath(matchOperator, pathModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
pathOrUrlMatchersValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,7 +163,6 @@ public partial class WireMockServer
|
||||
if (requestModel.Url is string url)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithUrl(url);
|
||||
pathOrUrlMatchersValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -179,17 +171,10 @@ public partial class WireMockServer
|
||||
{
|
||||
var matchOperator = StringUtils.ParseMatchOperator(urlModel.MatchOperator);
|
||||
requestBuilder = requestBuilder.WithUrl(matchOperator, urlModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
pathOrUrlMatchersValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pathOrUrlRequired && !pathOrUrlMatchersValid)
|
||||
{
|
||||
_settings.Logger.Error("Path or Url matcher is missing for this mapping, this mapping will not be added.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (requestModel.Methods != null)
|
||||
{
|
||||
var matchBehaviour = requestModel.MethodsRejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
||||
@@ -233,7 +218,7 @@ public partial class WireMockServer
|
||||
{
|
||||
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: { } }))
|
||||
{
|
||||
bool ignoreCase = paramModel.IgnoreCase == true;
|
||||
var ignoreCase = paramModel.IgnoreCase == true;
|
||||
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
|
||||
}
|
||||
}
|
||||
@@ -253,7 +238,7 @@ public partial class WireMockServer
|
||||
|
||||
private static IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
|
||||
{
|
||||
IResponseBuilder responseBuilder = Response.Create();
|
||||
var responseBuilder = Response.Create();
|
||||
|
||||
if (responseModel.Delay > 0)
|
||||
{
|
||||
|
||||
@@ -8,10 +8,7 @@ namespace WireMock.Net.Aspire.Tests;
|
||||
[ExcludeFromCodeCoverage]
|
||||
internal static class DockerUtils
|
||||
{
|
||||
public static bool IsDockerRunningLinuxContainerMode()
|
||||
{
|
||||
return IsDockerRunning() && IsLinuxContainerMode();
|
||||
}
|
||||
public static Lazy<bool> IsDockerRunningLinuxContainerMode => new(() => IsDockerRunning() && IsLinuxContainerMode());
|
||||
|
||||
private static bool IsDockerRunning()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Net.Aspire.Tests.Facts;
|
||||
|
||||
public sealed class DockerIsRunningInLinuxContainerModeFact : FactAttribute
|
||||
{
|
||||
private const string SkipReason = "Docker is not running in Linux container mode. Skipping test.";
|
||||
|
||||
public DockerIsRunningInLinuxContainerModeFact()
|
||||
{
|
||||
if (!DockerUtils.IsDockerRunningLinuxContainerMode.Value)
|
||||
{
|
||||
Skip = SkipReason;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
using System.Net.Http.Json;
|
||||
using FluentAssertions;
|
||||
using Projects;
|
||||
using WireMock.Net.Aspire.Tests.Facts;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace WireMock.Net.Aspire.Tests;
|
||||
@@ -11,15 +12,9 @@ public class IntegrationTests(ITestOutputHelper output)
|
||||
{
|
||||
private record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary);
|
||||
|
||||
[Fact]
|
||||
[DockerIsRunningInLinuxContainerModeFact]
|
||||
public async Task StartAppHostWithWireMockAndCreateHttpClientToCallTheMockedWeatherForecastEndpoint()
|
||||
{
|
||||
if (!DockerUtils.IsDockerRunningLinuxContainerMode())
|
||||
{
|
||||
output.WriteLine("Docker is not running in Linux container mode. Skipping test.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Arrange
|
||||
var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>();
|
||||
await using var app = await appHostBuilder.BuildAsync();
|
||||
@@ -44,15 +39,9 @@ public class IntegrationTests(ITestOutputHelper output)
|
||||
weatherForecasts2.Should().HaveCount(5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[DockerIsRunningInLinuxContainerModeFact]
|
||||
public async Task StartAppHostWithWireMockAndCreateWireMockAdminClientToCallTheAdminEndpoint()
|
||||
{
|
||||
if (!DockerUtils.IsDockerRunningLinuxContainerMode())
|
||||
{
|
||||
output.WriteLine("Docker is not running in Linux container mode. Skipping test.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Arrange
|
||||
var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>();
|
||||
await using var app = await appHostBuilder.BuildAsync();
|
||||
|
||||
37
test/WireMock.Net.TUnitTests/TUnitTests.cs
Normal file
37
test/WireMock.Net.TUnitTests/TUnitTests.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Net.TUnit;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
|
||||
namespace WireMock.Net.TUnitTests;
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
public class TUnitTests
|
||||
{
|
||||
[Test]
|
||||
public async Task Test_TUnitWireMockLogger()
|
||||
{
|
||||
// Assign
|
||||
var path = $"/foo_{Guid.NewGuid()}";
|
||||
|
||||
using var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
Logger = new TUnitWireMockLogger(TestContext.Current!.GetDefaultLogger())
|
||||
});
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.WithPath(path)
|
||||
.UsingGet())
|
||||
.RespondWith(Response.Create().WithBody("TUnit"));
|
||||
|
||||
// Act
|
||||
var response = await server.CreateClient().GetStringAsync($"{server.Url}{path}");
|
||||
|
||||
// Assert
|
||||
await Assert.That(response).IsEqualTo("TUnit");
|
||||
}
|
||||
}
|
||||
18
test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj
Normal file
18
test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj
Normal file
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="TUnit" Version="0.1.817" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.TUnit\WireMock.Net.TUnit.csproj" />
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Facts;
|
||||
|
||||
public sealed class IgnoreOnContinuousIntegrationFact : FactAttribute
|
||||
{
|
||||
private const string SkipReason = "Ignore when run via CI/CD";
|
||||
private static readonly bool IsContinuousIntegrationAzure = bool.TryParse(Environment.GetEnvironmentVariable("TF_BUILD"), out var isTF) && isTF;
|
||||
private static readonly bool IsContinuousIntegrationGithub = bool.TryParse(Environment.GetEnvironmentVariable("GITHUB_ACTIONS"), out var isGH) && isGH;
|
||||
private static readonly bool IsContinuousIntegration = IsContinuousIntegrationAzure || IsContinuousIntegrationGithub;
|
||||
|
||||
public IgnoreOnContinuousIntegrationFact()
|
||||
{
|
||||
if (IsContinuousIntegration)
|
||||
{
|
||||
Skip = SkipReason;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,26 @@ public class HttpRequestMessageHelperTests
|
||||
Check.That(await message.Content.ReadAsByteArrayAsync().ConfigureAwait(false)).ContainsExactly(Encoding.UTF8.GetBytes("hi"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HttpRequestMessageHelper_Create_TextPlain()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "0123", // or 83 in decimal
|
||||
BodyAsJson = 83,
|
||||
DetectedBodyType = BodyType.Json,
|
||||
DetectedBodyTypeFromContentType = BodyType.String
|
||||
};
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp, body);
|
||||
|
||||
// Act
|
||||
var message = HttpRequestMessageHelper.Create(request, "http://url");
|
||||
|
||||
// Assert
|
||||
Check.That(await message.Content!.ReadAsStringAsync().ConfigureAwait(false)).Equals("0123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HttpRequestMessageHelper_Create_Json()
|
||||
{
|
||||
@@ -64,7 +84,7 @@ public class HttpRequestMessageHelperTests
|
||||
var message = HttpRequestMessageHelper.Create(request, "http://url");
|
||||
|
||||
// Assert
|
||||
Check.That(await message.Content.ReadAsStringAsync().ConfigureAwait(false)).Equals("{\"x\":42}");
|
||||
Check.That(await message.Content!.ReadAsStringAsync().ConfigureAwait(false)).Equals("{\"x\":42}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if NET8_0_OR_GREATER
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using WireMock.Net.Xunit;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilders;
|
||||
|
||||
public sealed class ResponseWithProxyIntegrationTests(ITestOutputHelper output)
|
||||
{
|
||||
[Fact]
|
||||
public async Task Response_UsingTextPlain()
|
||||
{
|
||||
// Given
|
||||
using var server = await TestServer.New().Run();
|
||||
var port = server.GetPort();
|
||||
output.WriteLine($"Server running on port {port}");
|
||||
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
Port = 0,
|
||||
Logger = new TestOutputHelperWireMockLogger(output)
|
||||
};
|
||||
using var mockServer = WireMockServer.Start(settings);
|
||||
mockServer.Given(Request.Create().WithPath("/zipcode").UsingPatch())
|
||||
.RespondWith(Response.Create().WithProxy($"http://localhost:{port}"));
|
||||
|
||||
using var client = new HttpClient { BaseAddress = new Uri(mockServer.Urls[0]) };
|
||||
using var content = new ByteArrayContent("0123"u8.ToArray());
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
|
||||
|
||||
// When
|
||||
var response = await client.PatchAsync("/zipcode", content);
|
||||
|
||||
// Then
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
response.Content.Headers.GetValues("Content-Type").Should().BeEquivalentTo("text/plain; charset=utf-8");
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
result.Should().Be("0123");
|
||||
}
|
||||
|
||||
sealed class Disposable(Action dispose) : IDisposable
|
||||
{
|
||||
public void Dispose() => dispose();
|
||||
}
|
||||
|
||||
sealed class TestServer(WebApplication app) : IDisposable
|
||||
{
|
||||
private Disposable _disposable = new(() => { });
|
||||
|
||||
public static TestServer New()
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.WebHost.ConfigureKestrel(opts => opts.ListenAnyIP(0));
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapPatch("/zipcode", async (HttpRequest req) =>
|
||||
{
|
||||
var memory = new MemoryStream();
|
||||
await req.Body.CopyToAsync(memory);
|
||||
var content = Encoding.UTF8.GetString(memory.ToArray());
|
||||
return content;
|
||||
});
|
||||
return new(app);
|
||||
}
|
||||
|
||||
public int GetPort()
|
||||
=> app.Services.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>()!.Addresses
|
||||
.Select(x => new Uri(x).Port)
|
||||
.First();
|
||||
|
||||
public async ValueTask<TestServer> Run()
|
||||
{
|
||||
var started = new TaskCompletionSource();
|
||||
var host = app.Services.GetRequiredService<IHostApplicationLifetime>();
|
||||
host.ApplicationStarted.Register(() => started.SetResult());
|
||||
_ = Task.Run(() => app.RunAsync());
|
||||
await started.Task;
|
||||
_disposable = new(() => host.StopApplication());
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_disposable.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -11,9 +11,11 @@ using FluentAssertions;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NFluent;
|
||||
using WireMock.Admin.Settings;
|
||||
using RestEase;
|
||||
using WireMock.Client;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
@@ -244,6 +246,38 @@ public class WireMockServerAdminTests
|
||||
loggerMock.Verify(l => l.Info(It.Is<string>(s => s.StartsWith("The Static Mapping folder")), It.IsAny<object[]>()), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Mapping_WithoutPathOrUrl()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.StartWithAdminInterface();
|
||||
|
||||
// Act
|
||||
server.Given(Request.Create().UsingGet())
|
||||
.RespondWith(Response.Create());
|
||||
|
||||
// Assert
|
||||
var mapping = server.Mappings.First(m => !m.IsAdminInterface);
|
||||
var request = (Request) mapping.RequestMatcher;
|
||||
var pathMatcher = request.GetRequestMessageMatcher<RequestMessagePathMatcher>();
|
||||
pathMatcher.Should().BeNull();
|
||||
|
||||
var api = RestClient.For<IWireMockAdminApi>(server.Url);
|
||||
var mappingModels = await api.GetMappingsAsync();
|
||||
var mappingModel = mappingModels.First();
|
||||
mappingModel.Request.Path.Should().BeNull();
|
||||
mappingModel.Request.Url.Should().BeNull();
|
||||
|
||||
await api.DeleteMappingsAsync();
|
||||
|
||||
await api.PostMappingAsync(mappingModel);
|
||||
await api.GetMappingsAsync();
|
||||
mappingModels = await api.GetMappingsAsync();
|
||||
mappingModel = mappingModels.First();
|
||||
mappingModel.Request.Path.Should().BeNull();
|
||||
mappingModel.Request.Url.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockServer_Admin_Mappings_WithGuid_Get()
|
||||
{
|
||||
|
||||
@@ -8,6 +8,8 @@ using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
@@ -16,6 +18,7 @@ using NFluent;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Http;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Net.Tests.Facts;
|
||||
using WireMock.Net.Tests.Serialization;
|
||||
using WireMock.Net.Xunit;
|
||||
using WireMock.RequestBuilders;
|
||||
@@ -196,6 +199,66 @@ public partial class WireMockServerTests
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
private static string[] GetIPAddressesByFamily(AddressFamily addressFamily)
|
||||
{
|
||||
return NetworkInterface.GetAllNetworkInterfaces()
|
||||
.Where(ni => ni.OperationalStatus == OperationalStatus.Up)
|
||||
.SelectMany(ni => ni.GetIPProperties().UnicastAddresses)
|
||||
.Where(addr => addr.Address.AddressFamily == addressFamily)
|
||||
.Select(addr => addr.Address.ToString())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
[IgnoreOnContinuousIntegrationFact]
|
||||
public async Task WireMockServer_WithUrl0000_Should_Listen_On_All_IPs_IPv4()
|
||||
{
|
||||
// Arrange
|
||||
var port = PortUtils.FindFreeTcpPort();
|
||||
var IPv4 = GetIPAddressesByFamily(System.Net.Sockets.AddressFamily.InterNetwork);
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
Urls = ["http://0.0.0.0:" + port],
|
||||
};
|
||||
using var server = WireMockServer.Start(settings);
|
||||
|
||||
server.Given(Request.Create().WithPath("/*")).RespondWith(Response.Create().WithBody("x"));
|
||||
|
||||
foreach (var address in IPv4)
|
||||
{
|
||||
// Act
|
||||
var response = await new HttpClient().GetStringAsync("http://" + address + ":" + server.Ports[0] + "/foo").ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
response.Should().Be("x");
|
||||
}
|
||||
}
|
||||
|
||||
[IgnoreOnContinuousIntegrationFact]
|
||||
public async Task WireMockServer_WithUrl0000_Should_Listen_On_All_IPs_IPv6()
|
||||
{
|
||||
// Arrange
|
||||
var port = PortUtils.FindFreeTcpPort();
|
||||
var IPv6 = GetIPAddressesByFamily(System.Net.Sockets.AddressFamily.InterNetworkV6);
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
Urls = ["http://0.0.0.0:" + port],
|
||||
};
|
||||
using var server = WireMockServer.Start(settings);
|
||||
|
||||
server.Given(Request.Create().WithPath("/*")).RespondWith(Response.Create().WithBody("x"));
|
||||
|
||||
foreach (var address in IPv6)
|
||||
{
|
||||
// Act
|
||||
var response = await new HttpClient().GetStringAsync("http://[" + address + "]:" + server.Ports[0] + "/foo").ConfigureAwait(false);
|
||||
|
||||
// Assert
|
||||
response.Should().Be("x");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Should_respond_a_redirect_without_body()
|
||||
{
|
||||
@@ -248,7 +311,7 @@ public partial class WireMockServerTests
|
||||
// Act
|
||||
var response = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false);
|
||||
|
||||
// Asser.
|
||||
// Assert
|
||||
response.Should().Be("x");
|
||||
|
||||
server.Stop();
|
||||
@@ -274,7 +337,7 @@ public partial class WireMockServerTests
|
||||
await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false);
|
||||
watch.Stop();
|
||||
|
||||
// Asser.
|
||||
// Assert
|
||||
watch.ElapsedMilliseconds.Should().BeGreaterOrEqualTo(0);
|
||||
|
||||
server.Stop();
|
||||
@@ -662,4 +725,4 @@ public partial class WireMockServerTests
|
||||
server.Stop();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user