Compare commits

..

10 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
Stef Heyenrath
af124d556d 1.6.3 2024-09-07 09:36:33 +02:00
cocoon
60931f6273 Fix listen on AnyIP for url 0.0.0.0 (#1165)
* fix listen to AnyIP if url is 0.0.0.0

* Add Test for listenin on AnyIP for url 0.0.0.0

* add missing using, use var, indent, remove empty line

* remove assert for ipv4/v6 address list

* test only if NET6_0_OR_GREATER

* use same code style

* add missing +

* Asser. to Assert

* split single test into one for IPv4 and one for IPv6

* Create IgnoreOnContinuousIntegrationFact.cs

* Ignore tests if CI/CD

* change to file - scoped namespace and add GITHUB_ACTIONS

* use PortUtils.FindFreeTcpPort()

* add and use GetIPAddressesByFamily

* add using System.Net.Sockets

* use #if for both unit tests and include new helper method inside
2024-09-07 09:31:19 +02:00
Stef Heyenrath
b99a80e782 Update README.md (Fix NuGet and MyGet badges) 2024-09-06 15:11:30 +02:00
Stef Heyenrath
07c9aebf44 1.6.2 2024-09-04 18:50:59 +02:00
Stef Heyenrath
8348a7b9a3 Also update IWireMockMiddlewareOptions when settings are updated via admin interface (#1166)
* Also update IWireMockMiddlewareOptions when settings are updated via admin interface

* ci
2024-09-04 18:47:25 +02:00
Stef Heyenrath
9a49e6a1cd Upgrade Aspire to version 8.2.0 (#1163) 2024-08-31 17:06:30 +02:00
Stef Heyenrath
f82891c996 Fix version from "WireMock.Net.Aspire" 2024-08-29 18:51:25 +02:00
Stef Heyenrath
da100298c1 Update MappingConverter to correctly write the Matcher as C# code (#1152)
* Update MappingConverter to correctly write the Matcher as C# code

* .

* CSharpCodeMatcher

* tests

* .
2024-08-27 19:38:07 +02:00
61 changed files with 902 additions and 232 deletions

View File

@@ -1,3 +1,14 @@
# 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) # 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) - [#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] - [#1159](https://github.com/WireMock-Net/WireMock.Net/issues/1159) - RegexMatchTimeoutException when trying to parse HTTP version [bug]

View File

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

View File

@@ -1,6 +1,6 @@
rem https://github.com/StefH/GitHubReleaseNotes rem https://github.com/StefH/GitHubReleaseNotes
SET version=1.6.1 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% GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%

View File

@@ -1,5 +1,5 @@
# 1.6.1 (22 August 2024) # 1.6.3 (07 September 2024)
- #1160 Use default timeout for Regex [bug] - #1165 Fix listen on AnyIP for url 0.0.0.0
- #1159 RegexMatchTimeoutException when trying to parse HTTP version [bug] - #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 The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md

View File

@@ -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) | | | Official | Preview [:information_source:](https://github.com/WireMock-Net/WireMock.Net/wiki/MyGet-preview-versions) |
| - | - | - | | - | - | - |
| &nbsp;&nbsp;**WireMock.Net** | [![NuGet Badge WireMock.Net](https://buildstats.info/nuget/WireMock.Net)](https://www.nuget.org/packages/WireMock.Net) | [![MyGet Badge WireMock.Net](https://buildstats.info/myget/wiremock-net/WireMock.Net?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net) | &nbsp;&nbsp;**WireMock.Net** | [![NuGet Badge WireMock.Net](https://img.shields.io/nuget/v/WireMock.Net)](https://www.nuget.org/packages/WireMock.Net) | [![MyGet Badge WireMock.Net](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
| &nbsp;&nbsp;**WireMock.Net.StandAlone** | [![NuGet Badge WireMock.Net](https://buildstats.info/nuget/WireMock.Net.StandAlone)](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [![MyGet Badge WireMock.Net.StandAlone](https://buildstats.info/myget/wiremock-net/WireMock.Net.StandAlone?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone) | &nbsp;&nbsp;**WireMock.Net.StandAlone** | [![NuGet Badge WireMock.Net](https://img.shields.io/nuget/v/WireMock.Net.StandAlone)](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [![MyGet Badge WireMock.Net.StandAlone](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.StandAlone?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
| &nbsp;&nbsp;**WireMock.Net.FluentAssertions** | [![NuGet Badge WireMock.Net.FluentAssertions](https://buildstats.info/nuget/WireMock.Net.FluentAssertions)](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [![MyGet Badge WireMock.Net.FluentAssertions](https://buildstats.info/myget/wiremock-net/WireMock.Net.FluentAssertions?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions) | &nbsp;&nbsp;**WireMock.Net.FluentAssertions** | [![NuGet Badge WireMock.Net.FluentAssertions](https://img.shields.io/nuget/v/WireMock.Net.FluentAssertions)](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [![MyGet Badge WireMock.Net.FluentAssertions](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.FluentAssertions?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
| &nbsp;&nbsp;**WireMock.Net.Matchers.CSharpCode** | [![NuGet Badge WireMock.Net.Matchers.CSharpCode](https://buildstats.info/nuget/WireMock.Net.Matchers.CSharpCode)](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [![MyGet Badge WireMock.Net.Matchers.CSharpCode](https://buildstats.info/myget/wiremock-net/WireMock.Net.Matchers.CSharpCode?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode) | &nbsp;&nbsp;**WireMock.Net.Matchers.CSharpCode** | [![NuGet Badge WireMock.Net.Matchers.CSharpCode](https://img.shields.io/nuget/v/WireMock.Net.Matchers.CSharpCode)](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [![MyGet Badge WireMock.Net.Matchers.CSharpCode](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Matchers.CSharpCode?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
| &nbsp;&nbsp;**WireMock.Net.OpenApiParser** | [![NuGet Badge WireMock.Net.OpenApiParser](https://buildstats.info/nuget/WireMock.Net.OpenApiParser)](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [![MyGet Badge WireMock.Net.OpenApiParser](https://buildstats.info/myget/wiremock-net/WireMock.Net.OpenApiParser?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser) | &nbsp;&nbsp;**WireMock.Net.OpenApiParser** | [![NuGet Badge WireMock.Net.OpenApiParser](https://img.shields.io/nuget/v/WireMock.Net.OpenApiParser)](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [![MyGet Badge WireMock.Net.OpenApiParser](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.OpenApiParser?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
| &nbsp;&nbsp;**WireMock.Net.RestClient** | [![NuGet Badge WireMock.Net.RestClient](https://buildstats.info/nuget/WireMock.Net.RestClient)](https://www.nuget.org/packages/WireMock.Net.RestClient) | [![MyGet Badge WireMock.Net.RestClient](https://buildstats.info/myget/wiremock-net/WireMock.Net.RestClient?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient) | &nbsp;&nbsp;**WireMock.Net.RestClient** | [![NuGet Badge WireMock.Net.RestClient](https://img.shields.io/nuget/v/WireMock.Net.RestClient)](https://www.nuget.org/packages/WireMock.Net.RestClient) | [![MyGet Badge WireMock.Net.RestClient](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.RestClient?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
| &nbsp;&nbsp;**WireMock.Net.xUnit** | [![NuGet Badge WireMock.Net.xUnit](https://buildstats.info/nuget/WireMock.Net.xUnit)](https://www.nuget.org/packages/WireMock.Net.xUnit) | [![MyGet Badge WireMock.Net.xUnit](https://buildstats.info/myget/wiremock-net/WireMock.Net.xUnit?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit) | &nbsp;&nbsp;**WireMock.Net.xUnit** | [![NuGet Badge WireMock.Net.xUnit](https://img.shields.io/nuget/v/WireMock.Net.xUnit)](https://www.nuget.org/packages/WireMock.Net.xUnit) | [![MyGet Badge WireMock.Net.xUnit](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.xUnit?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.xUnit)
| &nbsp;&nbsp;**WireMock.Net.Testcontainers** | [![NuGet Badge WireMock.Net.Testcontainers](https://buildstats.info/nuget/WireMock.Net.Testcontainers)](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [![MyGet Badge WireMock.Net.Testcontainers](https://buildstats.info/myget/wiremock-net/WireMock.Net.Testcontainers?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers) | &nbsp;&nbsp;**WireMock.Net.Testcontainers** | [![NuGet Badge WireMock.Net.Testcontainers](https://img.shields.io/nuget/v/WireMock.Net.Testcontainers)](https://www.nuget.org/packages/WireMock.Net.Testcontainers) | [![MyGet Badge WireMock.Net.Testcontainers](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Testcontainers?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Testcontainers)
| &nbsp;&nbsp;**WireMock.Net.Aspire** | [![NuGet Badge WireMock.Net.Aspire](https://buildstats.info/nuget/WireMock.Net.Aspire)](https://www.nuget.org/packages/WireMock.Net.Aspire) | [![MyGet Badge WireMock.Net.Aspire](https://buildstats.info/myget/wiremock-net/WireMock.Net.Aspire?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire) | &nbsp;&nbsp;**WireMock.Net.Aspire** | [![NuGet Badge WireMock.Net.Aspire](https://img.shields.io/nuget/v/WireMock.Net.Aspire)](https://www.nuget.org/packages/WireMock.Net.Aspire) | [![MyGet Badge WireMock.Net.Aspire](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Net.Aspire?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Aspire)
| &nbsp;&nbsp;**WireMock.Org.RestClient** | [![NuGet Badge WireMock.Org.RestClient](https://buildstats.info/nuget/WireMock.Org.RestClient)](https://www.nuget.org/packages/WireMock.Org.RestClient) | [![MyGet Badge WireMock.Org.RestClient](https://buildstats.info/myget/wiremock-net/WireMock.Org.RestClient?includePreReleases=true)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient) | &nbsp;&nbsp;**WireMock.Org.RestClient** | [![NuGet Badge WireMock.Org.RestClient](https://img.shields.io/nuget/v/WireMock.Org.RestClient)](https://www.nuget.org/packages/WireMock.Org.RestClient) | [![MyGet Badge WireMock.Org.RestClient](https://img.shields.io/myget/wiremock-net/vpre/WireMock.Org.RestClient?includePreReleases=true&label=MyGet)](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
## :memo: Development ## :memo: Development

View File

@@ -33,6 +33,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Guids/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Guids/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Heyenrath/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Jmes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Levenstein/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=openapi/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=openapi/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pacticipant/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=Pacticipant/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=protobuf/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/UserDictionary/Words/=protobuf/@EntryIndexedValue">True</s:Boolean>

View File

@@ -53,8 +53,13 @@ jobs:
inputs: inputs:
script: | 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" 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-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-2.xml"
displayName: 'Execute Unit Tests with Coverage' displayName: 'Execute WireMock.Net.Aspire.Tests with Coverage'
- task: CmdLine@2 - task: CmdLine@2
displayName: 'Merge coverage files' displayName: 'Merge coverage files'

View File

@@ -17,7 +17,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.0" /> <PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -14,7 +14,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.0" /> <PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Version>0.0.1-preview-05</Version>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Description>Aspire extension to start a WireMock.Net server to stub an api.</Description> <Description>Aspire extension to start a WireMock.Net server to stub an api.</Description>
<AssemblyTitle>WireMock.Net.Aspire</AssemblyTitle> <AssemblyTitle>WireMock.Net.Aspire</AssemblyTitle>
@@ -36,7 +35,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aspire.Hosting" Version="8.0.0" /> <PackageReference Include="Aspire.Hosting" Version="8.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -10,6 +10,7 @@ using Stef.Validation;
using WireMock.Exceptions; using WireMock.Exceptions;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -92,6 +93,17 @@ internal class CSharpCodeMatcher : ICSharpCodeMatcher
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
} }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
private bool IsMatch(dynamic input, string pattern) private bool IsMatch(dynamic input, string pattern)
{ {
var isMatchWithString = input is string; var isMatchWithString = input is string;

View File

@@ -42,7 +42,7 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
return EmptyArray<AnyOf<string, StringPattern>>.Value; return EmptyArray<AnyOf<string, StringPattern>>.Value;
} }
public MatchOperator MatchOperator { get; } = MatchOperator.Or; public MatchOperator MatchOperator => MatchOperator.Or;
public MatchResult IsMatch(string? input) public MatchResult IsMatch(string? input)
{ {
@@ -76,5 +76,11 @@ internal class AzureADAuthenticationMatcher : IStringMatcher
return new MatchResult(MatchScores.Mismatch, ex); return new MatchResult(MatchScores.Mismatch, ex);
} }
} }
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
throw new NotImplementedException();
}
} }
#endif #endif

View File

@@ -130,7 +130,10 @@ public class MappingBuilder : IMappingBuilder
private IMapping[] GetNonAdminMappings() private IMapping[] GetNonAdminMappings()
{ {
return _options.Mappings.Values.Where(m => !m.IsAdminInterface).OrderBy(m => m.UpdatedAt).ToArray(); return _options.Mappings.Values
.Where(m => !m.IsAdminInterface)
.OrderBy(m => m.Guid)
.ToArray();
} }
private void RegisterMapping(IMapping mapping, bool saveToFile) private void RegisterMapping(IMapping mapping, bool saveToFile)

View File

@@ -2,7 +2,10 @@
using System.Net.Http.Headers; using System.Net.Http.Headers;
using AnyOfTypes; using AnyOfTypes;
using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -19,7 +22,7 @@ public class ContentTypeMatcher : WildcardMatcher
/// </summary> /// </summary>
/// <param name="pattern">The pattern.</param> /// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase (default false)</param> /// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(new[] { pattern }, ignoreCase) public ContentTypeMatcher(AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this([pattern], ignoreCase)
{ {
} }
@@ -29,7 +32,8 @@ public class ContentTypeMatcher : WildcardMatcher
/// <param name="matchBehaviour">The match behaviour.</param> /// <param name="matchBehaviour">The match behaviour.</param>
/// <param name="pattern">The pattern.</param> /// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">IgnoreCase (default false)</param> /// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour, new[] { pattern }, ignoreCase) public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern> pattern, bool ignoreCase = false) : this(matchBehaviour,
[pattern], ignoreCase)
{ {
} }
@@ -50,7 +54,7 @@ public class ContentTypeMatcher : WildcardMatcher
/// <param name="ignoreCase">IgnoreCase (default false)</param> /// <param name="ignoreCase">IgnoreCase (default false)</param>
public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase) public ContentTypeMatcher(MatchBehaviour matchBehaviour, AnyOf<string, StringPattern>[] patterns, bool ignoreCase = false) : base(matchBehaviour, patterns, ignoreCase)
{ {
_patterns = patterns; _patterns = Guard.NotNull(patterns);
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -72,4 +76,15 @@ public class ContentTypeMatcher : WildcardMatcher
/// <inheritdoc /> /// <inheritdoc />
public override string Name => nameof(ContentTypeMatcher); public override string Name => nameof(ContentTypeMatcher);
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}" +
$")";
}
} }

View File

@@ -4,7 +4,9 @@ using System;
using System.Linq; using System.Linq;
using AnyOfTypes; using AnyOfTypes;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -86,8 +88,20 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc />
public string Name => "ExactMatcher"; public string Name => nameof(ExactMatcher);
/// <inheritdoc /> /// <inheritdoc />
public bool IgnoreCase { get; } public bool IgnoreCase { get; }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_values)}" +
$")";
}
} }

View File

@@ -72,5 +72,11 @@ public class ExactObjectMatcher : IObjectMatcher
} }
/// <inheritdoc /> /// <inheritdoc />
public string Name => "ExactObjectMatcher"; public string Name => nameof(ExactObjectMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
} }

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using AnyOfTypes; using AnyOfTypes;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util; using WireMock.Util;
@@ -163,4 +164,16 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
} }

View File

@@ -156,6 +156,12 @@ public class GraphQLMatcher : IStringMatcher
/// <inheritdoc /> /// <inheritdoc />
public string Name => nameof(GraphQLMatcher); public string Name => nameof(GraphQLMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest) private static bool TryGetGraphQLRequest(string input, [NotNullWhen(true)] out GraphQLRequest? graphQLRequest)
{ {
try try

View File

@@ -16,4 +16,10 @@ public interface IMatcher
/// Gets the match behaviour. /// Gets the match behaviour.
/// </summary> /// </summary>
MatchBehaviour MatchBehaviour { get; } MatchBehaviour MatchBehaviour { get; }
/// <summary>
/// Get the C# code arguments.
/// </summary>
/// <returns></returns>
string GetCSharpCodeArguments();
} }

View File

@@ -7,6 +7,7 @@ using Newtonsoft.Json.Linq;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -89,7 +90,7 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
Exception? exception = null; Exception? exception = null;
// When input is null or byte[], return Mismatch. // When input is null or byte[], return Mismatch.
if (input != null && !(input is byte[])) if (input != null && input is not byte[])
{ {
try try
{ {
@@ -116,7 +117,18 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc /> /// <inheritdoc />
public string Name => "JsonPathMatcher"; public string Name => nameof(JsonPathMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
private double IsMatch(JToken jToken) private double IsMatch(JToken jToken)
{ {

View File

@@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -115,4 +116,15 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
/// <inheritdoc /> /// <inheritdoc />
public string Name => nameof(JmesPathMatcher); public string Name => nameof(JmesPathMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
} }

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions;
using WireMock.Util; using WireMock.Util;
using JsonUtils = WireMock.Util.JsonUtils; using JsonUtils = WireMock.Util.JsonUtils;
@@ -98,6 +99,18 @@ public class JsonMatcher : IJsonMatcher
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error); return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), error);
} }
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
$")";
}
/// <summary> /// <summary>
/// Compares the input against the matcher value /// Compares the input against the matcher value
/// </summary> /// </summary>

View File

@@ -1,5 +1,8 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using WireMock.Extensions;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
/// <summary> /// <summary>
@@ -34,4 +37,16 @@ public class JsonPartialMatcher : AbstractJsonPartialMatcher
var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, MatchOperator.Or, value); var exactStringMatcher = new ExactMatcher(MatchBehaviour.AcceptOnMatch, IgnoreCase, MatchOperator.Or, value);
return exactStringMatcher.IsMatch(input).IsPerfect(); return exactStringMatcher.IsMatch(input).IsPerfect();
} }
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
$")";
}
} }

View File

@@ -1,5 +1,8 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using WireMock.Extensions;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
/// <summary> /// <summary>
@@ -34,4 +37,16 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase); var wildcardStringMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, IgnoreCase);
return wildcardStringMatcher.IsMatch(input).IsPerfect(); return wildcardStringMatcher.IsMatch(input).IsPerfect();
} }
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(Regex)}" +
$")";
}
} }

View File

@@ -9,6 +9,7 @@ using Stef.Validation;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Json; using WireMock.Json;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -136,4 +137,15 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
/// <inheritdoc /> /// <inheritdoc />
public string Name => nameof(LinqMatcher); public string Name => nameof(LinqMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
} }

View File

@@ -3,6 +3,7 @@
#if MIMEKIT #if MIMEKIT
using System; using System;
using MimeKit; using MimeKit;
using WireMock.Extensions;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Matchers.Helpers; using WireMock.Matchers.Helpers;
using WireMock.Models; using WireMock.Models;
@@ -60,13 +61,13 @@ public class MimePartMatcher : IMatcher
ContentTransferEncodingMatcher = contentTransferEncodingMatcher; ContentTransferEncodingMatcher = contentTransferEncodingMatcher;
ContentMatcher = contentMatcher; ContentMatcher = contentMatcher;
_funcs = new[] _funcs =
{ [
mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect, mp => ContentTypeMatcher?.IsMatch(GetContentTypeAsString(mp.ContentType)) ?? MatchScores.Perfect,
mp => ContentDispositionMatcher?.IsMatch(mp.ContentDisposition.ToString().Replace("Content-Disposition: ", string.Empty)) ?? 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 => ContentTransferEncodingMatcher?.IsMatch(mp.ContentTransferEncoding.ToString().ToLowerInvariant()) ?? MatchScores.Perfect,
MatchOnContent MatchOnContent
}; ];
} }
/// <summary> /// <summary>
@@ -94,6 +95,12 @@ public class MimePartMatcher : IMatcher
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
} }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
private MatchResult MatchOnContent(MimePart mimePart) private MatchResult MatchOnContent(MimePart mimePart)
{ {
if (ContentMatcher == null) if (ContentMatcher == null)

View File

@@ -3,7 +3,9 @@
using System; using System;
using System.Linq; using System.Linq;
using AnyOfTypes; using AnyOfTypes;
using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -70,5 +72,14 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
} }
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } = MatchOperator.Or; public MatchOperator MatchOperator => MatchOperator.Or;
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}" +
$")";
}
} }

View File

@@ -89,6 +89,12 @@ public class ProtoBufMatcher : IProtoBufMatcher
return DecodeAsync(input, false, cancellationToken); return DecodeAsync(input, false, cancellationToken);
} }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "NotImplemented";
}
private async Task<object?> DecodeAsync(byte[]? input, bool throwException, CancellationToken cancellationToken) private async Task<object?> DecodeAsync(byte[]? input, bool throwException, CancellationToken cancellationToken)
{ {
if (input == null) if (input == null)

View File

@@ -10,6 +10,7 @@ using WireMock.Constants;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.RegularExpressions; using WireMock.RegularExpressions;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -22,6 +23,7 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
{ {
private readonly AnyOf<string, StringPattern>[] _patterns; private readonly AnyOf<string, StringPattern>[] _patterns;
private readonly Regex[] _expressions; private readonly Regex[] _expressions;
private readonly bool _useRegexExtended;
/// <inheritdoc /> /// <inheritdoc />
public MatchBehaviour MatchBehaviour { get; } public MatchBehaviour MatchBehaviour { get; }
@@ -77,10 +79,11 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
{ {
_patterns = Guard.NotNull(patterns); _patterns = Guard.NotNull(patterns);
IgnoreCase = ignoreCase; IgnoreCase = ignoreCase;
_useRegexExtended = useRegexExtended;
MatchBehaviour = matchBehaviour; MatchBehaviour = matchBehaviour;
MatchOperator = matchOperator; MatchOperator = matchOperator;
RegexOptions options = RegexOptions.Compiled | RegexOptions.Multiline; var options = RegexOptions.Compiled | RegexOptions.Multiline;
if (ignoreCase) if (ignoreCase)
{ {
@@ -126,4 +129,16 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
/// <inheritdoc /> /// <inheritdoc />
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(_useRegexExtended)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
} }

View File

@@ -8,6 +8,7 @@ using SimMetrics.Net.Metric;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -88,6 +89,18 @@ public class SimMetricsMatcher : IStringMatcher
return MatchBehaviourHelper.Convert(MatchBehaviour, score); return MatchBehaviourHelper.Convert(MatchBehaviour, score);
} }
/// <inheritdoc />
public virtual string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{_simMetricType.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
private IStringMetric GetStringMetricType() private IStringMetric GetStringMetricType()
{ {
return _simMetricType switch return _simMetricType switch

View File

@@ -6,6 +6,7 @@ using AnyOfTypes;
using Stef.Validation; using Stef.Validation;
using WireMock.Extensions; using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using WireMock.Util;
namespace WireMock.Matchers; namespace WireMock.Matchers;
@@ -70,6 +71,18 @@ public class WildcardMatcher : RegexMatcher
/// <inheritdoc /> /// <inheritdoc />
public override string Name => nameof(WildcardMatcher); public override string Name => nameof(WildcardMatcher);
/// <inheritdoc />
public override string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
$")";
}
private static AnyOf<string, StringPattern>[] CreateArray(AnyOf<string, StringPattern>[] patterns) private static AnyOf<string, StringPattern>[] CreateArray(AnyOf<string, StringPattern>[] patterns)
{ {
return patterns return patterns

View File

@@ -10,6 +10,7 @@ using WireMock.Extensions;
using WireMock.Models; using WireMock.Models;
using Stef.Validation; using Stef.Validation;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Util;
#if !NETSTANDARD1_3 #if !NETSTANDARD1_3
using Wmhelp.XPath2; using Wmhelp.XPath2;
#endif #endif
@@ -89,11 +90,6 @@ public class XPathMatcher : IStringMatcher
return CreateMatchResult(score); return CreateMatchResult(score);
} }
private MatchResult CreateMatchResult(double score, Exception? exception = null)
{
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
/// <inheritdoc /> /// <inheritdoc />
public AnyOf<string, StringPattern>[] GetPatterns() public AnyOf<string, StringPattern>[] GetPatterns()
{ {
@@ -106,6 +102,23 @@ public class XPathMatcher : IStringMatcher
/// <inheritdoc /> /// <inheritdoc />
public string Name => nameof(XPathMatcher); public string Name => nameof(XPathMatcher);
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return $"new {Name}" +
$"(" +
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
$"null, " +
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}" +
$")";
}
private MatchResult CreateMatchResult(double score, Exception? exception = null)
{
return new MatchResult(MatchBehaviourHelper.Convert(MatchBehaviour, score), exception);
}
private sealed class XPathEvaluator private sealed class XPathEvaluator
{ {
private XmlDocument? _xmlDocument; private XmlDocument? _xmlDocument;
@@ -130,6 +143,7 @@ public class XPathMatcher : IStringMatcher
{ {
return _xpathNavigator == null ? [] : patterns.Select(pattern => true.Equals(Evaluate(_xpathNavigator, pattern, xmlNamespaceMap))).ToArray(); return _xpathNavigator == null ? [] : patterns.Select(pattern => true.Equals(Evaluate(_xpathNavigator, pattern, xmlNamespaceMap))).ToArray();
} }
private object Evaluate(XPathNavigator navigator, AnyOf<string, StringPattern> pattern, IEnumerable<XmlNamespace>? xmlNamespaceMap) private object Evaluate(XPathNavigator navigator, AnyOf<string, StringPattern> pattern, IEnumerable<XmlNamespace>? xmlNamespaceMap)
{ {
var xpath = $"boolean({pattern.GetPattern()})"; var xpath = $"boolean({pattern.GetPattern()})";

View File

@@ -75,8 +75,15 @@ namespace WireMock.Owin
private static void Listen(KestrelServerOptions kestrelOptions, HostUrlDetails urlDetail, Action<ListenOptions> configure) 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. // 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); kestrelOptions.ListenLocalhost(urlDetail.Port, configure);
return; return;
@@ -113,4 +120,4 @@ namespace WireMock.Owin
} }
} }
} }
#endif #endif

View File

@@ -1,5 +1,6 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using System;
using Stef.Validation; using Stef.Validation;
using WireMock.Settings; using WireMock.Settings;
@@ -7,21 +8,31 @@ namespace WireMock.Owin;
internal static class WireMockMiddlewareOptionsHelper internal static class WireMockMiddlewareOptionsHelper
{ {
public static IWireMockMiddlewareOptions InitFromSettings(WireMockServerSettings settings, IWireMockMiddlewareOptions? options = null) public static IWireMockMiddlewareOptions InitFromSettings(
WireMockServerSettings settings,
IWireMockMiddlewareOptions? options = null,
Action<IWireMockMiddlewareOptions>? postConfigure = null
)
{ {
Guard.NotNull(settings); Guard.NotNull(settings);
options ??= new WireMockMiddlewareOptions(); options ??= new WireMockMiddlewareOptions();
options.FileSystemHandler = settings.FileSystemHandler; options.AllowBodyForAllHttpMethods = settings.AllowBodyForAllHttpMethods;
options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit; options.AllowOnlyDefinedHttpStatusCodeInResponse = settings.AllowOnlyDefinedHttpStatusCodeInResponse;
options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit; options.AllowPartialMapping = settings.AllowPartialMapping;
options.Logger = settings.Logger;
options.DisableJsonBodyParsing = settings.DisableJsonBodyParsing; options.DisableJsonBodyParsing = settings.DisableJsonBodyParsing;
options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously; options.DisableRequestBodyDecompressing = settings.DisableRequestBodyDecompressing;
options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
options.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry; options.DoNotSaveDynamicResponseInLogEntry = settings.DoNotSaveDynamicResponseInLogEntry;
options.FileSystemHandler = settings.FileSystemHandler;
options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
options.Logger = settings.Logger;
options.MaxRequestLogCount = settings.MaxRequestLogCount;
options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
options.QueryParameterMultipleValueSupport = settings.QueryParameterMultipleValueSupport; options.QueryParameterMultipleValueSupport = settings.QueryParameterMultipleValueSupport;
options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;
options.SaveUnmatchedRequests = settings.SaveUnmatchedRequests;
if (settings.CustomCertificateDefined) if (settings.CustomCertificateDefined)
{ {
@@ -32,6 +43,8 @@ internal static class WireMockMiddlewareOptionsHelper
options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword; options.X509CertificatePassword = settings.CertificateSettings.X509CertificatePassword;
} }
postConfigure?.Invoke(options);
return options; return options;
} }
} }

View File

@@ -23,16 +23,11 @@ using static WireMock.Util.CSharpFormatter;
namespace WireMock.Serialization; namespace WireMock.Serialization;
internal class MappingConverter internal class MappingConverter(MatcherMapper mapper)
{ {
private static readonly string AcceptOnMatch = MatchBehaviour.AcceptOnMatch.GetFullyQualifiedEnumValue(); private static readonly string AcceptOnMatch = MatchBehaviour.AcceptOnMatch.GetFullyQualifiedEnumValue();
private readonly MatcherMapper _mapper; private readonly MatcherMapper _mapper = Guard.NotNull(mapper);
public MappingConverter(MatcherMapper mapper)
{
_mapper = Guard.NotNull(mapper);
}
public string ToCSharpCode(IMapping mapping, MappingConverterSettings? settings = null) public string ToCSharpCode(IMapping mapping, MappingConverterSettings? settings = null)
{ {
@@ -77,26 +72,26 @@ internal class MappingConverter
sb.AppendLine(" .Given(Request.Create()"); sb.AppendLine(" .Given(Request.Create()");
sb.AppendLine($" .UsingMethod({To1Or2Or3Arguments(methodMatcher?.MatchBehaviour, methodMatcher?.MatchOperator, methodMatcher?.Methods, HttpRequestMethod.GET)})"); sb.AppendLine($" .UsingMethod({To1Or2Or3Arguments(methodMatcher?.MatchBehaviour, methodMatcher?.MatchOperator, methodMatcher?.Methods, HttpRequestMethod.GET)})");
if (pathMatcher is { Matchers: { } }) if (pathMatcher?.Matchers != null)
{ {
sb.AppendLine($" .WithPath({To1Or2Arguments(pathMatcher.MatchOperator, pathMatcher.Matchers)})"); sb.AppendLine($" .WithPath({To1Or2Arguments(pathMatcher.MatchOperator, pathMatcher.Matchers)})");
} }
else if (urlMatcher is { Matchers: { } }) else if (urlMatcher?.Matchers != null)
{ {
sb.AppendLine($" .WithUrl({To1Or2Arguments(urlMatcher.MatchOperator, urlMatcher.Matchers)})"); sb.AppendLine($" .WithUrl({To1Or2Arguments(urlMatcher.MatchOperator, urlMatcher.Matchers)})");
} }
foreach (var paramsMatcher in paramsMatchers) foreach (var paramsMatcher in paramsMatchers.Where(pm => pm.Matchers != null))
{ {
sb.AppendLine($" .WithParam({To1Or2Or3Arguments(paramsMatcher.Key, paramsMatcher.MatchBehaviour, paramsMatcher.Matchers!)})"); sb.AppendLine($" .WithParam({To2Or3Arguments(paramsMatcher.Key, paramsMatcher.MatchBehaviour, paramsMatcher.Matchers!)})");
} }
if (clientIPMatcher is { Matchers: { } }) if (clientIPMatcher?.Matchers != null)
{ {
sb.AppendLine($" .WithClientIP({ToValueArguments(GetStringArray(clientIPMatcher.Matchers))})"); sb.AppendLine($" .WithClientIP({ToValueArguments(GetStringArray(clientIPMatcher.Matchers))})");
} }
foreach (var headerMatcher in headerMatchers.Where(h => h.Matchers is { })) foreach (var headerMatcher in headerMatchers.Where(h => h.Matchers != null))
{ {
var headerBuilder = new StringBuilder($"\"{headerMatcher.Name}\", {ToValueArguments(GetStringArray(headerMatcher.Matchers!))}, true"); var headerBuilder = new StringBuilder($"\"{headerMatcher.Name}\", {ToValueArguments(GetStringArray(headerMatcher.Matchers!))}, true");
if (headerMatcher.MatchOperator != MatchOperator.Or) if (headerMatcher.MatchOperator != MatchOperator.Or)
@@ -106,7 +101,7 @@ internal class MappingConverter
sb.AppendLine($" .WithHeader({headerBuilder})"); sb.AppendLine($" .WithHeader({headerBuilder})");
} }
foreach (var cookieMatcher in cookieMatchers.Where(h => h.Matchers is { })) foreach (var cookieMatcher in cookieMatchers.Where(c => c.Matchers != null))
{ {
sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)"); sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)");
} }
@@ -117,7 +112,7 @@ internal class MappingConverter
} }
#if GRAPHQL #if GRAPHQL
if (requestMessageGraphQLMatcher is { Matchers: { } }) if (requestMessageGraphQLMatcher?.Matchers != null)
{ {
if (requestMessageGraphQLMatcher.Matchers.OfType<GraphQLMatcher>().FirstOrDefault() is { } graphQLMatcher && graphQLMatcher.GetPatterns().Any()) if (requestMessageGraphQLMatcher.Matchers.OfType<GraphQLMatcher>().FirstOrDefault() is { } graphQLMatcher && graphQLMatcher.GetPatterns().Any())
{ {
@@ -127,7 +122,7 @@ internal class MappingConverter
#endif #endif
#if MIMEKIT #if MIMEKIT
if (requestMessageMultiPartMatcher is { Matchers: { } }) if (requestMessageMultiPartMatcher?.Matchers != null)
{ {
if (requestMessageMultiPartMatcher.Matchers.OfType<MimePartMatcher>().Any()) if (requestMessageMultiPartMatcher.Matchers.OfType<MimePartMatcher>().Any())
{ {
@@ -137,13 +132,13 @@ internal class MappingConverter
#endif #endif
#if PROTOBUF #if PROTOBUF
if (requestMessageProtoBufMatcher is { Matcher: { } }) if (requestMessageProtoBufMatcher?.Matcher != null)
{ {
sb.AppendLine(" // .WithBodyAsProtoBuf() is not yet supported"); sb.AppendLine(" // .WithBodyAsProtoBuf() is not yet supported");
} }
#endif #endif
if (requestMessageBodyMatcher is { Matchers: { } }) if (requestMessageBodyMatcher?.Matchers != null)
{ {
var firstMatcher = requestMessageBodyMatcher.Matchers.FirstOrDefault(); var firstMatcher = requestMessageBodyMatcher.Matchers.FirstOrDefault();
@@ -154,15 +149,15 @@ internal class MappingConverter
break; break;
case JsonMatcher jsonMatcher: case JsonMatcher jsonMatcher:
{ {
var matcherType = jsonMatcher.GetType().Name; var matcherType = jsonMatcher.GetType().Name;
sb.AppendLine($" .WithBody(new {matcherType}("); sb.AppendLine($" .WithBody(new {matcherType}(");
sb.AppendLine($" value: {ConvertToAnonymousObjectDefinition(jsonMatcher.Value, 3)},"); sb.AppendLine($" value: {ConvertToAnonymousObjectDefinition(jsonMatcher.Value, 3)},");
sb.AppendLine($" ignoreCase: {ToCSharpBooleanLiteral(jsonMatcher.IgnoreCase)},"); sb.AppendLine($" ignoreCase: {ToCSharpBooleanLiteral(jsonMatcher.IgnoreCase)},");
sb.AppendLine($" regex: {ToCSharpBooleanLiteral(jsonMatcher.Regex)}"); sb.AppendLine($" regex: {ToCSharpBooleanLiteral(jsonMatcher.Regex)}");
sb.AppendLine(@" ))"); sb.AppendLine(@" ))");
break; break;
} }
} }
} }
@@ -309,7 +304,7 @@ internal class MappingConverter
Response = new ResponseModel() Response = new ResponseModel()
}; };
if (methodMatcher is { Methods: { } }) if (methodMatcher != null)
{ {
mappingModel.Request.Methods = methodMatcher.Methods; mappingModel.Request.Methods = methodMatcher.Methods;
mappingModel.Request.MethodsRejectOnMatch = methodMatcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null; mappingModel.Request.MethodsRejectOnMatch = methodMatcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : null;
@@ -321,7 +316,7 @@ internal class MappingConverter
mappingModel.Request.HttpVersion = httpVersionMatcher.HttpVersion; mappingModel.Request.HttpVersion = httpVersionMatcher.HttpVersion;
} }
if (clientIPMatcher is { Matchers: { } }) if (clientIPMatcher?.Matchers != null)
{ {
var clientIPMatchers = _mapper.Map(clientIPMatcher.Matchers); var clientIPMatchers = _mapper.Map(clientIPMatcher.Matchers);
mappingModel.Request.Path = new ClientIPModel mappingModel.Request.Path = new ClientIPModel
@@ -331,7 +326,7 @@ internal class MappingConverter
}; };
} }
if (pathMatcher is { Matchers: { } }) if (pathMatcher?.Matchers != null)
{ {
var pathMatchers = _mapper.Map(pathMatcher.Matchers); var pathMatchers = _mapper.Map(pathMatcher.Matchers);
mappingModel.Request.Path = new PathModel mappingModel.Request.Path = new PathModel
@@ -340,7 +335,7 @@ internal class MappingConverter
MatchOperator = pathMatchers?.Length > 1 ? pathMatcher.MatchOperator.ToString() : null MatchOperator = pathMatchers?.Length > 1 ? pathMatcher.MatchOperator.ToString() : null
}; };
} }
else if (urlMatcher is { Matchers: { } }) else if (urlMatcher?.Matchers != null)
{ {
var urlMatchers = _mapper.Map(urlMatcher.Matchers); var urlMatchers = _mapper.Map(urlMatcher.Matchers);
mappingModel.Request.Url = new UrlModel mappingModel.Request.Url = new UrlModel
@@ -538,7 +533,7 @@ internal class MappingConverter
return stringMatchers.SelectMany(m => m.GetPatterns()).Select(p => p.GetPattern()).ToArray(); return stringMatchers.SelectMany(m => m.GetPatterns()).Select(p => p.GetPattern()).ToArray();
} }
private static string To1Or2Or3Arguments(string key, MatchBehaviour? matchBehaviour, IReadOnlyList<IStringMatcher> matchers) private static string To2Or3Arguments(string key, MatchBehaviour? matchBehaviour, IReadOnlyList<IStringMatcher> matchers)
{ {
var sb = new StringBuilder($"\"{key}\", "); var sb = new StringBuilder($"\"{key}\", ");
@@ -547,7 +542,7 @@ internal class MappingConverter
sb.AppendFormat("{0}, ", matchBehaviour.Value.GetFullyQualifiedEnumValue()); sb.AppendFormat("{0}, ", matchBehaviour.Value.GetFullyQualifiedEnumValue());
} }
sb.AppendFormat("{0}", ToValueArguments(GetStringArray(matchers), string.Empty)); sb.AppendFormat("{0}", MappingConverterUtils.ToCSharpCodeArguments(matchers));
return sb.ToString(); return sb.ToString();
} }
@@ -566,7 +561,16 @@ internal class MappingConverter
private static string To1Or2Arguments(MatchOperator? matchOperator, IReadOnlyList<IStringMatcher> matchers) private static string To1Or2Arguments(MatchOperator? matchOperator, IReadOnlyList<IStringMatcher> matchers)
{ {
return To1Or2Arguments(matchOperator, GetStringArray(matchers), string.Empty); var sb = new StringBuilder();
if (matchOperator.HasValue && matchOperator != MatchOperator.Or)
{
sb.AppendFormat("{0}, ", matchOperator.Value.GetFullyQualifiedEnumValue());
}
sb.AppendFormat("{0}", MappingConverterUtils.ToCSharpCodeArguments(matchers));
return sb.ToString();
} }
private static string To1Or2Arguments(MatchOperator? matchOperator, string[]? values, string defaultValue) private static string To1Or2Arguments(MatchOperator? matchOperator, string[]? values, string defaultValue)

View File

@@ -18,6 +18,7 @@ using WireMock.Http;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Matchers.Request; using WireMock.Matchers.Request;
using WireMock.Owin;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
using WireMock.ResponseProviders; using WireMock.ResponseProviders;
using WireMock.Serialization; using WireMock.Serialization;
@@ -321,29 +322,27 @@ public partial class WireMockServer
InitSettings(_settings); InitSettings(_settings);
// _options
if (settings.GlobalProcessingDelay != null)
{
_options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
}
_options.AllowBodyForAllHttpMethods = settings.AllowBodyForAllHttpMethods;
_options.AllowPartialMapping = settings.AllowPartialMapping;
_options.HandleRequestsSynchronously = settings.HandleRequestsSynchronously;
_options.MaxRequestLogCount = settings.MaxRequestLogCount;
_options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;
// _settings & _options
#if USE_ASPNETCORE #if USE_ASPNETCORE
if (Enum.TryParse<CorsPolicyOptions>(settings.CorsPolicyOptions, true, out var corsPolicyOptions)) if (Enum.TryParse<CorsPolicyOptions>(settings.CorsPolicyOptions, true, out var corsPolicyOptions))
{ {
_settings.CorsPolicyOptions = corsPolicyOptions; _settings.CorsPolicyOptions = corsPolicyOptions;
_options.CorsPolicyOptions = corsPolicyOptions;
} }
_options.ClientCertificateMode = _settings.ClientCertificateMode;
_options.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
#endif #endif
WireMockMiddlewareOptionsHelper.InitFromSettings(_settings, _options, o =>
{
if (settings.GlobalProcessingDelay != null)
{
o.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
}
#if USE_ASPNETCORE
o.CorsPolicyOptions = corsPolicyOptions;
o.ClientCertificateMode = _settings.ClientCertificateMode;
o.AcceptAnyClientCertificate = _settings.AcceptAnyClientCertificate;
#endif
});
return ResponseMessageBuilder.Create(200, "Settings updated"); return ResponseMessageBuilder.Create(200, "Settings updated");
} }
#endregion Settings #endregion Settings

View File

@@ -20,7 +20,6 @@ using WireMock.Exceptions;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Http; using WireMock.Http;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Matchers.Request;
using WireMock.Models; using WireMock.Models;
using WireMock.Owin; using WireMock.Owin;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
@@ -369,9 +368,10 @@ public partial class WireMockServer : IWireMockServer
} }
} }
WireMockMiddlewareOptionsHelper.InitFromSettings(settings, _options); WireMockMiddlewareOptionsHelper.InitFromSettings(settings, _options, o =>
{
_options.LogEntries.CollectionChanged += LogEntries_CollectionChanged; o.LogEntries.CollectionChanged += LogEntries_CollectionChanged;
});
_matcherMapper = new MatcherMapper(_settings); _matcherMapper = new MatcherMapper(_settings);
_mappingConverter = new MappingConverter(_matcherMapper); _mappingConverter = new MappingConverter(_matcherMapper);
@@ -649,13 +649,11 @@ public partial class WireMockServer : IWireMockServer
{ {
if (settings.AllowBodyForAllHttpMethods == true) if (settings.AllowBodyForAllHttpMethods == true)
{ {
_options.AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods;
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to True"); _settings.Logger.Info("AllowBodyForAllHttpMethods is set to True");
} }
if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true) if (settings.AllowOnlyDefinedHttpStatusCodeInResponse == true)
{ {
_options.AllowOnlyDefinedHttpStatusCodeInResponse = _settings.AllowOnlyDefinedHttpStatusCodeInResponse;
_settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True"); _settings.Logger.Info("AllowOnlyDefinedHttpStatusCodeInResponse is set to True");
} }

View File

@@ -0,0 +1,23 @@
// Copyright © WireMock.Net
using System.Collections.Generic;
using System.Linq;
using AnyOfTypes;
using WireMock.Extensions;
using WireMock.Matchers;
using WireMock.Models;
namespace WireMock.Util;
internal static class MappingConverterUtils
{
internal static string ToCSharpCodeArguments(IReadOnlyList<IMatcher> matchers)
{
return string.Join(", ", matchers.Select(m => m.GetCSharpCodeArguments()));
}
internal static string ToCSharpCodeArguments(AnyOf<string, StringPattern>[] patterns)
{
return string.Join(", ", patterns.Select(p => CSharpFormatter.ToCSharpStringLiteral(p.GetPattern())));
}
}

View File

@@ -18,7 +18,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="8.0.0" /> <PackageReference Include="Aspire.Hosting.AppHost" Version="8.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -8,10 +8,7 @@ namespace WireMock.Net.Aspire.Tests;
[ExcludeFromCodeCoverage] [ExcludeFromCodeCoverage]
internal static class DockerUtils internal static class DockerUtils
{ {
public static bool IsDockerRunningLinuxContainerMode() public static Lazy<bool> IsDockerRunningLinuxContainerMode => new(() => IsDockerRunning() && IsLinuxContainerMode());
{
return IsDockerRunning() && IsLinuxContainerMode();
}
private static bool IsDockerRunning() private static bool IsDockerRunning()
{ {

View File

@@ -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;
}
}
}

View File

@@ -3,6 +3,7 @@
using System.Net.Http.Json; using System.Net.Http.Json;
using FluentAssertions; using FluentAssertions;
using Projects; using Projects;
using WireMock.Net.Aspire.Tests.Facts;
using Xunit.Abstractions; using Xunit.Abstractions;
namespace WireMock.Net.Aspire.Tests; namespace WireMock.Net.Aspire.Tests;
@@ -11,15 +12,9 @@ public class IntegrationTests(ITestOutputHelper output)
{ {
private record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary); private record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary);
[Fact] [DockerIsRunningInLinuxContainerModeFact]
public async Task StartAppHostWithWireMockAndCreateHttpClientToCallTheMockedWeatherForecastEndpoint() public async Task StartAppHostWithWireMockAndCreateHttpClientToCallTheMockedWeatherForecastEndpoint()
{ {
if (!DockerUtils.IsDockerRunningLinuxContainerMode())
{
output.WriteLine("Docker is not running in Linux container mode. Skipping test.");
return;
}
// Arrange // Arrange
var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>(); var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>();
await using var app = await appHostBuilder.BuildAsync(); await using var app = await appHostBuilder.BuildAsync();
@@ -44,15 +39,9 @@ public class IntegrationTests(ITestOutputHelper output)
weatherForecasts2.Should().HaveCount(5); weatherForecasts2.Should().HaveCount(5);
} }
[Fact] [DockerIsRunningInLinuxContainerModeFact]
public async Task StartAppHostWithWireMockAndCreateWireMockAdminClientToCallTheAdminEndpoint() public async Task StartAppHostWithWireMockAndCreateWireMockAdminClientToCallTheAdminEndpoint()
{ {
if (!DockerUtils.IsDockerRunningLinuxContainerMode())
{
output.WriteLine("Docker is not running in Linux container mode. Skipping test.");
return;
}
// Arrange // Arrange
var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>(); var appHostBuilder = await DistributedApplicationTestingBuilder.CreateAsync<WireMock_Net_Aspire_TestAppHost>();
await using var app = await appHostBuilder.BuildAsync(); await using var app = await appHostBuilder.BuildAsync();

View File

@@ -12,7 +12,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Aspire.Hosting.Testing" Version="8.0.0" /> <PackageReference Include="Aspire.Hosting.Testing" Version="8.2.0" />
<PackageReference Include="Codecov" Version="1.13.0" /> <PackageReference Include="Codecov" Version="1.13.0" />
<PackageReference Include="coverlet.msbuild" Version="6.0.2"> <PackageReference Include="coverlet.msbuild" Version="6.0.2">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View File

@@ -47,6 +47,7 @@ message HelloReply {
.WithPath("/grpc/greet.Greeter/SayHello") .WithPath("/grpc/greet.Greeter/SayHello")
.WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloRequest", protoBufJsonMatcher) .WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloRequest", protoBufJsonMatcher)
) )
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc") .WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloReply", .WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloReply",
@@ -66,6 +67,7 @@ message HelloReply {
.WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher) .WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher)
) )
.WithProtoDefinition(ProtoDefinition) .WithProtoDefinition(ProtoDefinition)
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc") .WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply", .WithBodyAsProtoBuf("greet.HelloReply",
@@ -86,6 +88,7 @@ message HelloReply {
.WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher) .WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher)
) )
.WithProtoDefinition("my-greeter") .WithProtoDefinition("my-greeter")
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc") .WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply", .WithBodyAsProtoBuf("greet.HelloReply",
@@ -106,6 +109,7 @@ message HelloReply {
.WithBodyAsProtoBuf("greet.HelloRequest") .WithBodyAsProtoBuf("greet.HelloRequest")
) )
.WithProtoDefinition("my-greeter") .WithProtoDefinition("my-greeter")
.WithGuid(_guidUtilsMock.Object.NewGuid())
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc") .WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply", .WithBodyAsProtoBuf("greet.HelloReply",

View File

@@ -2,8 +2,8 @@
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("/foo1") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo1", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("p1", "xyz") .WithParam("p1", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "xyz"))
) )
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05") .WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create() .RespondWith(Response.Create()

View File

@@ -2,25 +2,7 @@
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("POST")
.WithPath("/users/post1") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
city = "Amsterdam",
country = "The Netherlands"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
);
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath("/users/post2")
.WithBody(new JsonPartialMatcher( .WithBody(new JsonPartialMatcher(
value: new value: new
{ {
@@ -37,23 +19,11 @@ server
Some ""value"" in Line2") Some ""value"" in Line2")
); );
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
)
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody("1")
);
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("POST")
.WithPath("/foo2") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo2", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("p2", "abc") .WithParam("p2", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "abc"))
.WithHeader("h1", "W/\"234f2q3r\"", true) .WithHeader("h1", "W/\"234f2q3r\"", true)
) )
.WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd") .WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd")
@@ -64,10 +34,28 @@ server
.WithBody("2") .WithBody("2")
); );
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
city = "Amsterdam",
country = "The Netherlands"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
);
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("DELETE") .UsingMethod("DELETE")
.WithUrl("https://localhost/test") .WithUrl(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "https://localhost/test", false, WireMock.Matchers.MatchOperator.Or))
) )
.WithGuid("c9929240-7ae8-4a5d-8ed8-0913479f6eeb") .WithGuid("c9929240-7ae8-4a5d-8ed8-0913479f6eeb")
.RespondWith(Response.Create() .RespondWith(Response.Create()
@@ -108,3 +96,15 @@ text
}) })
); );
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo1", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("p1", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "xyz"))
)
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBody("1")
);

View File

@@ -30,6 +30,7 @@ using WireMock.ResponseBuilders;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
using WireMock.Types; using WireMock.Types;
using WireMock.Util;
using Xunit; using Xunit;
namespace WireMock.Net.Tests.AdminApi; namespace WireMock.Net.Tests.AdminApi;
@@ -39,6 +40,14 @@ public partial class WireMockAdminApiTests
{ {
private static readonly VerifySettings VerifySettings = new(); private static readonly VerifySettings VerifySettings = new();
private readonly Mock<IGuidUtils> _guidUtilsMock = new();
public WireMockAdminApiTests()
{
var startGuid = 1000;
_guidUtilsMock.Setup(g => g.NewGuid()).Returns(() => new Guid($"98fae52e-76df-47d9-876f-2ee32e93{startGuid++}"));
}
static WireMockAdminApiTests() static WireMockAdminApiTests()
{ {
VerifyNewtonsoftJson.Enable(VerifySettings); VerifyNewtonsoftJson.Enable(VerifySettings);

View File

@@ -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;
}
}
}

View File

@@ -32,6 +32,35 @@
Body: { msg: "Hello world!"} Body: { msg: "Hello world!"}
} }
}, },
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
UpdatedAt: 2023-01-14 15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post1,
IgnoreCase: false
}
]
},
Methods: [
POST
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
Request: Hello?
},
IgnoreCase: false,
Regex: false
}
}
},
Response: {}
},
{ {
Guid: 98fae52e-76df-47d9-876f-2ee32e931002, Guid: 98fae52e-76df-47d9-876f-2ee32e931002,
UpdatedAt: 2023-01-14 15:16:17, UpdatedAt: 2023-01-14 15:16:17,
@@ -106,31 +135,33 @@
Response: {} Response: {}
}, },
{ {
Guid: 98fae52e-76df-47d9-876f-2ee32e931001, Guid: 98fae52e-76df-47d9-876f-2ee32e931004,
UpdatedAt: 2023-01-14 15:16:17, UpdatedAt: 2023-01-14 15:16:17,
Request: { Request: {
Path: { Path: {
Matchers: [ Matchers: [
{ {
Name: WildcardMatcher, Name: WildcardMatcher,
Pattern: /users/post1, Pattern: /regex,
IgnoreCase: false IgnoreCase: false
} }
] ]
}, },
Methods: [ Methods: [
POST GET
], ],
Body: { Params: [
Matcher: { {
Name: JsonMatcher, Name: foo,
Pattern: { Matchers: [
Request: Hello? {
}, Name: RegexMatcher,
IgnoreCase: false, Pattern: .*,
Regex: false IgnoreCase: false
}
]
} }
} ]
}, },
Response: {} Response: {}
} }

View File

@@ -2,8 +2,8 @@
builder builder
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("/foo") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("test", "it.Length < 10") .WithParam("test", new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, "it.Length < 10"))
) )
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce") .WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
.RespondWith(Response.Create() .RespondWith(Response.Create()
@@ -13,7 +13,24 @@ builder
builder builder
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("POST")
.WithPath("/users/post2") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
.RespondWith(Response.Create()
);
builder
.Given(Request.Create()
.UsingMethod("POST")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher( .WithBody(new JsonMatcher(
value: new value: new
{ {
@@ -31,7 +48,7 @@ builder
builder builder
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("POST")
.WithPath("/form-urlencoded") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/form-urlencoded", false, WireMock.Matchers.MatchOperator.Or))
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true) .WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
.WithBody("name=John Doe") .WithBody("name=John Doe")
) )
@@ -41,18 +58,11 @@ builder
builder builder
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("GET")
.WithPath("/users/post1") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/regex", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher( .WithParam("foo", new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, ".*", false, true, WireMock.Matchers.MatchOperator.Or))
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
) )
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001") .WithGuid("98fae52e-76df-47d9-876f-2ee32e931004")
.RespondWith(Response.Create() .RespondWith(Response.Create()
); );

View File

@@ -2,8 +2,8 @@
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("/foo") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("test", "it.Length < 10") .WithParam("test", new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, "it.Length < 10"))
) )
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce") .WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
.RespondWith(Response.Create() .RespondWith(Response.Create()
@@ -13,7 +13,24 @@ server
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("POST")
.WithPath("/users/post2") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher(
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
)
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001")
.RespondWith(Response.Create()
);
server
.Given(Request.Create()
.UsingMethod("POST")
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher( .WithBody(new JsonMatcher(
value: new value: new
{ {
@@ -31,7 +48,7 @@ server
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("POST")
.WithPath("/form-urlencoded") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/form-urlencoded", false, WireMock.Matchers.MatchOperator.Or))
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true) .WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
.WithBody("name=John Doe") .WithBody("name=John Doe")
) )
@@ -41,18 +58,11 @@ server
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("POST") .UsingMethod("GET")
.WithPath("/users/post1") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/regex", false, WireMock.Matchers.MatchOperator.Or))
.WithBody(new JsonMatcher( .WithParam("foo", new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, ".*", false, true, WireMock.Matchers.MatchOperator.Or))
value: new
{
Request = "Hello?"
},
ignoreCase: false,
regex: false
))
) )
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931001") .WithGuid("98fae52e-76df-47d9-876f-2ee32e931004")
.RespondWith(Response.Create() .RespondWith(Response.Create()
); );

View File

@@ -32,6 +32,34 @@
Body: { msg: "Hello world!"} Body: { msg: "Hello world!"}
} }
}, },
{
Guid: 98fae52e-76df-47d9-876f-2ee32e931001,
UpdatedAt: 2023-01-14T15:16:17,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /users/post1,
IgnoreCase: false
}
]
},
Methods: [
POST
],
Body: {
Matcher: {
Name: JsonMatcher,
Pattern: {
Request: Hello?
},
IgnoreCase: false,
Regex: false
}
}
}
},
{ {
Guid: 98fae52e-76df-47d9-876f-2ee32e931002, Guid: 98fae52e-76df-47d9-876f-2ee32e931002,
UpdatedAt: 2023-01-14T15:16:17, UpdatedAt: 2023-01-14T15:16:17,
@@ -104,31 +132,33 @@
} }
}, },
{ {
Guid: 98fae52e-76df-47d9-876f-2ee32e931001, Guid: 98fae52e-76df-47d9-876f-2ee32e931004,
UpdatedAt: 2023-01-14T15:16:17, UpdatedAt: 2023-01-14T15:16:17,
Request: { Request: {
Path: { Path: {
Matchers: [ Matchers: [
{ {
Name: WildcardMatcher, Name: WildcardMatcher,
Pattern: /users/post1, Pattern: /regex,
IgnoreCase: false IgnoreCase: false
} }
] ]
}, },
Methods: [ Methods: [
POST GET
], ],
Body: { Params: [
Matcher: { {
Name: JsonMatcher, Name: foo,
Pattern: { Matchers: [
Request: Hello? {
}, Name: RegexMatcher,
IgnoreCase: false, Pattern: .*,
Regex: false IgnoreCase: false
}
]
} }
} ]
} }
} }
] ]

View File

@@ -102,6 +102,13 @@ public class MappingBuilderTests
.WithHeader("Content-Type", "application/x-www-form-urlencoded") .WithHeader("Content-Type", "application/x-www-form-urlencoded")
.WithBody(new FormUrlEncodedMatcher(["name=John Doe", "email=johndoe@example.com"])) .WithBody(new FormUrlEncodedMatcher(["name=John Doe", "email=johndoe@example.com"]))
).RespondWith(Response.Create()); ).RespondWith(Response.Create());
_sut.Given(Request.Create()
.WithPath("/regex")
.WithParam("foo", new RegexMatcher(".*"))
.UsingGet()
)
.RespondWith(Response.Create());
} }
[Fact] [Fact]
@@ -190,9 +197,9 @@ public class MappingBuilderTests
_sut.SaveMappingsToFolder(null); _sut.SaveMappingsToFolder(null);
// Verify // Verify
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(4)); _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Exactly(5));
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(4)); _fileSystemHandlerMock.Verify(fs => fs.FolderExists(mappingFolder), Times.Exactly(5));
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(4)); _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(5));
_fileSystemHandlerMock.VerifyNoOtherCalls(); _fileSystemHandlerMock.VerifyNoOtherCalls();
} }
@@ -208,8 +215,8 @@ public class MappingBuilderTests
// Verify // Verify
_fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never); _fileSystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Never);
_fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(4)); _fileSystemHandlerMock.Verify(fs => fs.FolderExists(path), Times.Exactly(5));
_fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(4)); _fileSystemHandlerMock.Verify(fs => fs.WriteMappingFile(It.IsAny<string>(), It.IsAny<string>()), Times.Exactly(5));
_fileSystemHandlerMock.VerifyNoOtherCalls(); _fileSystemHandlerMock.VerifyNoOtherCalls();
} }
} }

View File

@@ -29,7 +29,7 @@ public class ExactObjectMatcherTests
object checkValue = new byte[] { 1, 2 }; object checkValue = new byte[] { 1, 2 };
// Act // Act
var matcher = new ExactObjectMatcher(new byte[] { 1, 2 }); var matcher = new ExactObjectMatcher([1, 2]);
var score = matcher.IsMatch(checkValue).Score; var score = matcher.IsMatch(checkValue).Score;
// Assert // Assert

View File

@@ -0,0 +1,177 @@
using FluentAssertions;
using WireMock.Matchers;
using Xunit;
namespace WireMock.Net.Tests.Matchers;
public class MatcherTests
{
[Fact]
public void ContentTypeMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new ContentTypeMatcher("application/json");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new ContentTypeMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"application/json\", false)");
}
[Fact]
public void ExactMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new ExactMatcher("test");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, \"test\")");
}
[Fact]
public void ExactObjectMatcher_GetCSharpCodeArguments_ShouldReturnNotImplemented()
{
// Arrange
var matcher = new ExactObjectMatcher(new { Name = "test" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("NotImplemented");
}
[Fact]
public void FormUrlEncodedMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new FormUrlEncodedMatcher("key=value");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new FormUrlEncodedMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"key=value\", false, WireMock.Matchers.MatchOperator.Or)");
}
[Fact]
public void JmesPathMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JmesPathMatcher("expression");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new JmesPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"expression\")");
}
[Fact]
public void JsonMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JsonMatcher(new { key = "value" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().StartWith("new JsonMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
}
[Fact]
public void JsonPartialMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JsonPartialMatcher(new { key = "value" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().StartWith("new JsonPartialMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
}
[Fact]
public void JsonPartialWildcardMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new JsonPartialWildcardMatcher(new { key = "value" });
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().StartWith("new JsonPartialWildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
}
[Fact]
public void LinqMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new LinqMatcher("it.Contains(\"test\"");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"it.Contains(\\\"test\\\"\")");
}
[Fact]
public void RegexMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new RegexMatcher("pattern");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"pattern\", false, true, WireMock.Matchers.MatchOperator.Or)");
}
[Fact]
public void SimMetricsMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new SimMetricsMatcher("test");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new SimMetricsMatcher.Levenstein(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"test\", SimMetrics.Net.SimMetricType.Levenstein, WireMock.Matchers.MatchOperator.Average)");
}
[Fact]
public void WildcardMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new WildcardMatcher("pattern");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"pattern\", false, WireMock.Matchers.MatchOperator.Or)");
}
[Fact]
public void XPathMatcher_GetCSharpCodeArguments_ShouldReturnCorrectArguments()
{
// Arrange
var matcher = new XPathMatcher("pattern1");
// Act
var result = matcher.GetCSharpCodeArguments();
// Assert
result.Should().Be("new XPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, null, \"pattern1\")");
}
}

View File

@@ -92,11 +92,17 @@ public class CustomPathParamMatcher : IStringMatcher
public MatchOperator MatchOperator { get; } public MatchOperator MatchOperator { get; }
/// <inheritdoc />
public string GetCSharpCodeArguments()
{
return "// TODO: CustomPathParamMatcher";
}
private static string[] GetPathParts(string? path) private static string[] GetPathParts(string? path)
{ {
if (path is null) if (path is null)
{ {
return new string[0]; return [];
} }
var hashMarkIndex = path.IndexOf('#'); var hashMarkIndex = path.IndexOf('#');

View File

@@ -1,8 +1,8 @@
builder builder
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("test_path") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", "42") .WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99") .WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true) .WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true) .WithCookie("c-key", "c-value", true)

View File

@@ -2,8 +2,8 @@
builder builder
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("test_path") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", "42") .WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99") .WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true) .WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true) .WithCookie("c-key", "c-value", true)

View File

@@ -1,8 +1,8 @@
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("test_path") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", "42") .WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99") .WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true) .WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true) .WithCookie("c-key", "c-value", true)

View File

@@ -2,8 +2,8 @@
server server
.Given(Request.Create() .Given(Request.Create()
.UsingMethod("GET") .UsingMethod("GET")
.WithPath("test_path") .WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "test_path", false, WireMock.Matchers.MatchOperator.Or))
.WithParam("q", "42") .WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
.WithClientIP("112.123.100.99") .WithClientIP("112.123.100.99")
.WithHeader("h-key", "h-value", true) .WithHeader("h-key", "h-value", true)
.WithCookie("c-key", "c-value", true) .WithCookie("c-key", "c-value", true)

View File

@@ -8,6 +8,8 @@ using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
@@ -16,6 +18,7 @@ using NFluent;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Http; using WireMock.Http;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Net.Tests.Facts;
using WireMock.Net.Tests.Serialization; using WireMock.Net.Tests.Serialization;
using WireMock.Net.Xunit; using WireMock.Net.Xunit;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
@@ -196,6 +199,66 @@ public partial class WireMockServerTests
} }
#endif #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] [Fact]
public async Task WireMockServer_Should_respond_a_redirect_without_body() public async Task WireMockServer_Should_respond_a_redirect_without_body()
{ {
@@ -248,7 +311,7 @@ public partial class WireMockServerTests
// Act // Act
var response = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false); var response = await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false);
// Asser. // Assert
response.Should().Be("x"); response.Should().Be("x");
server.Stop(); server.Stop();
@@ -274,7 +337,7 @@ public partial class WireMockServerTests
await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false); await new HttpClient().GetStringAsync("http://localhost:" + server.Ports[0] + "/foo").ConfigureAwait(false);
watch.Stop(); watch.Stop();
// Asser. // Assert
watch.ElapsedMilliseconds.Should().BeGreaterOrEqualTo(0); watch.ElapsedMilliseconds.Should().BeGreaterOrEqualTo(0);
server.Stop(); server.Stop();
@@ -662,4 +725,4 @@ public partial class WireMockServerTests
server.Stop(); server.Stop();
} }
#endif #endif
} }