Compare commits

..

2 Commits

Author SHA1 Message Date
Stef Heyenrath
0406f642e8 IgnoreOnContinuousIntegrationFact 2024-09-09 20:28:45 +02:00
Stef Heyenrath
11d090037e Skip unit tests when Docker is not running in Linux container mode using DockerIsRunningInLinuxContainerModeFact 2024-09-09 18:43:18 +02:00
22 changed files with 61 additions and 453 deletions

View File

@@ -20,9 +20,7 @@ jobs:
- uses: actions/checkout@v4
- name: 'Execute Tests'
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
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
linux-build-and-run:
name: Run Tests on Linux
@@ -35,9 +33,7 @@ jobs:
- uses: actions/checkout@v4
- name: 'Execute Tests'
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
run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
- name: Install .NET Aspire workload
run: dotnet workload install aspire

View File

@@ -1,15 +1,3 @@
# 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]

View File

@@ -4,7 +4,7 @@
</PropertyGroup>
<PropertyGroup>
<VersionPrefix>1.6.4</VersionPrefix>
<VersionPrefix>1.6.3</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="2024.2.0" PrivateAssets="All" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.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.32.0.97167">
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.29.0.95321">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

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

View File

@@ -1,13 +1,5 @@
# 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]
# 1.6.3 (07 September 2024)
- #1165 Fix listen on AnyIP for url 0.0.0.0
- #1154 Listen on all ips [bug]
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -131,10 +131,6 @@ 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
@@ -321,14 +317,6 @@ 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
@@ -381,8 +369,6 @@ 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}

View File

@@ -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.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.dotnet.excludeTestProjects=true /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,14 +52,13 @@ 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-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'
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'
- 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-aspire.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-2.xml"
displayName: 'Execute WireMock.Net.Aspire.Tests with Coverage'
- task: CmdLine@2

View File

@@ -1,25 +0,0 @@
// 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;
}
}

View File

@@ -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.17" />
<PackageReference Include="CS-Script" Version="4.8.13" />
</ItemGroup>
</Project>

View File

@@ -1,80 +0,0 @@
// 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}";
}
}

View File

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

View File

@@ -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.10.0" />
<PackageReference Include="Testcontainers" Version="[3.9.0]" />
</ItemGroup>
<ItemGroup>

View File

@@ -73,6 +73,8 @@ 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}";
}

View File

@@ -9,7 +9,6 @@ using Newtonsoft.Json;
using Stef.Validation;
using WireMock.Constants;
using WireMock.Types;
using WireMock.Util;
namespace WireMock.Http;
@@ -34,14 +33,12 @@ internal static class HttpRequestMessageHelper
MediaTypeHeaderValue.TryParse(value, out contentType);
}
var bodyData = requestMessage.BodyData;
httpRequestMessage.Content = bodyData?.GetBodyType() switch
httpRequestMessage.Content = requestMessage.BodyData?.DetectedBodyType switch
{
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),
BodyType.Bytes => ByteArrayContentHelper.Create(requestMessage.BodyData.BodyAsBytes!, contentType),
BodyType.Json => StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType),
BodyType.String => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
BodyType.FormUrlEncoded => StringContentHelper.Create(requestMessage.BodyData.BodyAsString!, contentType),
_ => httpRequestMessage.Content
};

View File

@@ -136,37 +136,30 @@ namespace WireMock.Owin.Mappers
return responseMessage.FaultPercentage == null || _randomizerDouble.Generate() <= responseMessage.FaultPercentage;
}
private async Task<byte[]?> GetNormalBodyAsync(IResponseMessage responseMessage) {
var bodyData = responseMessage.BodyData;
switch (bodyData?.GetBodyType())
private async Task<byte[]?> GetNormalBodyAsync(IResponseMessage responseMessage)
{
switch (responseMessage.BodyData?.DetectedBodyType)
{
case BodyType.String:
case BodyType.FormUrlEncoded:
return (bodyData.Encoding ?? _utf8NoBom).GetBytes(bodyData.BodyAsString!);
return (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString!);
case BodyType.Json:
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);
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);
#if PROTOBUF
case BodyType.ProtoBuf:
var protoDefinition = bodyData.ProtoDefinition?.Invoke().Text;
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinition, bodyData.ProtoBufMessageType, bodyData.BodyAsJson).ConfigureAwait(false);
var protoDefinition = responseMessage.BodyData.ProtoDefinition?.Invoke().Text;
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinition, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson).ConfigureAwait(false);
#endif
case BodyType.Bytes:
return bodyData.BodyAsBytes;
return responseMessage.BodyData.BodyAsBytes;
case BodyType.File:
return _options.FileSystemHandler?.ReadResponseBodyAsFile(bodyData.BodyAsFile!);
case BodyType.MultiPart:
_options.Logger.Warn("MultiPart body type is not handled!");
break;
case BodyType.None:
break;
return _options.FileSystemHandler?.ReadResponseBodyAsFile(responseMessage.BodyData.BodyAsFile!);
}
return null;
@@ -178,7 +171,10 @@ namespace WireMock.Owin.Mappers
AppendResponseHeader(
response,
HttpKnownHeaderNames.Date,
[ DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture) ]
new[]
{
DateTime.UtcNow.ToString(CultureInfo.InvariantCulture.DateTimeFormat.RFC1123Pattern, CultureInfo.InvariantCulture)
}
);
// Set other headers

View File

@@ -623,7 +623,7 @@ public partial class WireMockServer
{
var requestModel = DeserializeObject<RequestModel>(requestMessage);
var request = (Request)InitRequestBuilder(requestModel);
var request = (Request)InitRequestBuilder(requestModel, false)!;
var dict = new Dictionary<ILogEntry, RequestMatchResult>();
foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))

View File

@@ -36,13 +36,17 @@ 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);
var requestBuilder = InitRequestBuilder(mappingModel.Request, true);
if (requestBuilder == null)
{
return null;
}
var respondProvider = Given(requestBuilder, mappingModel.SaveToFile == true);
@@ -122,9 +126,9 @@ public partial class WireMockServer
return respondProvider.Guid;
}
private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
private IRequestBuilder? InitRequestBuilder(RequestModel requestModel, bool pathOrUrlRequired)
{
var requestBuilder = Request.Create();
IRequestBuilder requestBuilder = Request.Create();
if (requestModel.ClientIP != null)
{
@@ -142,11 +146,13 @@ public partial class WireMockServer
}
}
bool pathOrUrlMatchersValid = false;
if (requestModel.Path != null)
{
if (requestModel.Path is string path)
{
requestBuilder = requestBuilder.WithPath(path);
pathOrUrlMatchersValid = true;
}
else
{
@@ -155,6 +161,7 @@ public partial class WireMockServer
{
var matchOperator = StringUtils.ParseMatchOperator(pathModel.MatchOperator);
requestBuilder = requestBuilder.WithPath(matchOperator, pathModel.Matchers.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
pathOrUrlMatchersValid = true;
}
}
}
@@ -163,6 +170,7 @@ public partial class WireMockServer
if (requestModel.Url is string url)
{
requestBuilder = requestBuilder.WithUrl(url);
pathOrUrlMatchersValid = true;
}
else
{
@@ -171,10 +179,17 @@ 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;
@@ -218,7 +233,7 @@ public partial class WireMockServer
{
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: { } }))
{
var ignoreCase = paramModel.IgnoreCase == true;
bool ignoreCase = paramModel.IgnoreCase == true;
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
}
}
@@ -238,7 +253,7 @@ public partial class WireMockServer
private static IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
{
var responseBuilder = Response.Create();
IResponseBuilder responseBuilder = Response.Create();
if (responseModel.Delay > 0)
{

View File

@@ -1,37 +0,0 @@
// 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");
}
}

View File

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

View File

@@ -49,26 +49,6 @@ 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()
{
@@ -84,7 +64,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]

View File

@@ -1,111 +0,0 @@
// 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

View File

@@ -11,11 +11,9 @@ using FluentAssertions;
using Moq;
using Newtonsoft.Json;
using NFluent;
using RestEase;
using WireMock.Client;
using WireMock.Admin.Settings;
using WireMock.Handlers;
using WireMock.Logging;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server;
@@ -246,38 +244,6 @@ 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()
{