mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-11-13 12:23:42 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc4cdfae50 | ||
|
|
f19d94acae | ||
|
|
90819f031e | ||
|
|
471745f704 | ||
|
|
7db5b562d8 | ||
|
|
e4389333a1 | ||
|
|
f0969e9618 | ||
|
|
84f4109a7c | ||
|
|
ee0f890795 | ||
|
|
2b165eb6a1 |
No files matched your search
@@ -1,3 +1,18 @@
|
||||
# 2.18.0 (22 September 2026)
|
||||
- [#1510](https://github.com/wiremock/WireMock.Net/pull/1510) - WireMock.Net.OpenApiParser: fix depencency on RamlToOpenApiConverter.SourceOnly [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1508](https://github.com/wiremock/WireMock.Net/issues/1508) - Transitive Dependency Conflict with Microsoft.OpenApi in 2.16.0 [bug]
|
||||
|
||||
# 2.17.0 (21 September 2026)
|
||||
- [#1509](https://github.com/wiremock/WireMock.Net/pull/1509) - Revert to RamlToOpenApiConverter.SourceOnly [bug] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 2.16.0 (19 September 2026)
|
||||
- [#1502](https://github.com/wiremock/WireMock.Net/pull/1502) - Fix #1501: Generate WhenStateIs/WillSetStateTo correctly in ToCSharpCode contributed by [Bafyn](https://github.com/Bafyn)
|
||||
- [#1503](https://github.com/wiremock/WireMock.Net/pull/1503) - Fix FormUrlEncodedMatcher (+ refactor values / matchers logic) contributed by [StefH](https://github.com/StefH)
|
||||
- [#1504](https://github.com/wiremock/WireMock.Net/pull/1504) - Update SharpYaml package to version 2.5.1 [dependencies] contributed by [johnthcall](https://github.com/johnthcall)
|
||||
- [#1505](https://github.com/wiremock/WireMock.Net/pull/1505) - Upgrade dependency RamlToOpenApiConverter to version 0.40.0 [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||
- [#1500](https://github.com/wiremock/WireMock.Net/issues/1500) - Sending a form-urlencoded body with a repeated field name returns HTTP 500 [bug]
|
||||
- [#1501](https://github.com/wiremock/WireMock.Net/issues/1501) - Generated C# code for stateful (Scenario) mappings does not compile and drops the WhenStateIs condition [bug]
|
||||
|
||||
# 2.15.0 (15 August 2026)
|
||||
- [#1495](https://github.com/wiremock/WireMock.Net/pull/1495) - Fix #1494: `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the MatchOperator argument [bug] contributed by [Bafyn](https://github.com/Bafyn)
|
||||
- [#1497](https://github.com/wiremock/WireMock.Net/pull/1497) - Fix WithParam RejectOnMatch inverting the match result #1496 [bug] contributed by [Bafyn](https://github.com/Bafyn)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.15.0</VersionPrefix>
|
||||
<VersionPrefix>2.18.0</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.400" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.401" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=2.15.0
|
||||
SET version=2.18.0
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# 2.15.0 (15 August 2026)
|
||||
- #1495 Fix #1494: `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the MatchOperator argument [bug]
|
||||
- #1497 Fix WithParam RejectOnMatch inverting the match result #1496 [bug]
|
||||
- #1499 Update Testcontainers [bug]
|
||||
- #1494 `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the `MatchOperator` argument [bug]
|
||||
- #1496 `WithParam(key, MatchBehaviour.RejectOnMatch, values)` inverts the match result [bug]
|
||||
# 2.18.0 (22 September 2026)
|
||||
- #1510 WireMock.Net.OpenApiParser: fix depencency on RamlToOpenApiConverter.SourceOnly [bug]
|
||||
- #1508 Transitive Dependency Conflict with Microsoft.OpenApi in 2.16.0 [bug]
|
||||
|
||||
The full release notes can be found here: https://github.com/wiremock/WireMock.Net/blob/master/CHANGELOG.md
|
||||
@@ -1,9 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using RestEase;
|
||||
using WireMock.Admin.Settings;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.IO;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using SharpYaml.Model;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Net.StandAlone;
|
||||
using WireMock.RequestBuilders;
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WireMock.Net" Version="2.12.0" />
|
||||
<PackageReference Include="WireMock.Net" Version="2.15.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
|
||||
|
||||
+1
-3
@@ -6,15 +6,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" />
|
||||
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="3.7.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="3.10.2" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -46,7 +46,7 @@ public interface IBodyData
|
||||
/// <summary>
|
||||
/// The body as Form UrlEncoded dictionary.
|
||||
/// </summary>
|
||||
IDictionary<string, string>? BodyAsFormUrlEncoded { get; set; }
|
||||
IDictionary<string, WireMockList<string>>? BodyAsFormUrlEncoded { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type (detection based on body content).
|
||||
|
||||
@@ -46,6 +46,98 @@ public class WireMockList<T> : List<T>
|
||||
/// <param name="values">The values to set.</param>
|
||||
public static implicit operator WireMockList<T>(T[] values) => new(values);
|
||||
|
||||
/// <summary>
|
||||
/// Operator for equality comparison from WireMockList to T
|
||||
/// </summary>
|
||||
public static bool operator ==(WireMockList<T>? left, T? right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (left?.Count == 1 && Equals(left[0], right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator for equality comparison from T to WireMockList
|
||||
/// </summary>
|
||||
public static bool operator ==(T? left, WireMockList<T>? right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (right?.Count == 1 && Equals(left, right[0]))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operator for inequality comparison from WireMockList to T
|
||||
/// </summary>
|
||||
public static bool operator !=(WireMockList<T>? left, T? right) => !(left == right);
|
||||
|
||||
/// <summary>
|
||||
/// Operator for inequality comparison from T to WireMockList
|
||||
/// </summary>
|
||||
public static bool operator !=(T? left, WireMockList<T>? right) => !(left == right);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified object is equal to the current instance.
|
||||
/// Two <see cref="WireMockList{T}"/> instances are equal if they contain the same elements in the same order.
|
||||
/// </summary>
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj is WireMockList<T> other)
|
||||
{
|
||||
if (Count != other.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
if (!Equals(this[i], other[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance based on its elements.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = 17;
|
||||
foreach (var item in this)
|
||||
{
|
||||
hashCode = hashCode * 31 + (item?.GetHashCode() ?? 0);
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string" /> that represents this instance.
|
||||
/// </summary>
|
||||
@@ -61,7 +153,7 @@ public class WireMockList<T> : List<T>
|
||||
{
|
||||
return strValue;
|
||||
}
|
||||
|
||||
|
||||
return this[0]?.ToString() ?? string.Empty;
|
||||
|
||||
default:
|
||||
|
||||
@@ -70,7 +70,7 @@ public class CSharpCodeMatcher : ICSharpCodeMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(CSharpCodeMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
|
||||
@@ -126,7 +126,7 @@ public class SystemTextJsonPathMatcher : ISystemTextJsonPathMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(SystemTextJsonPathMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
|
||||
@@ -80,10 +80,10 @@ public class ContentTypeMatcher : WildcardMatcher
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(ContentTypeMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] {{ {MappingConverterUtils.ToCSharpCodeArguments(_patterns)} }}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}" +
|
||||
$")";
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class ExactMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(ExactMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
@@ -21,7 +21,7 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
private readonly List<(WildcardMatcher Key, WildcardMatcher? Value)> _pairs = [];
|
||||
private readonly List<(WildcardMatcher Key, WildcardMatcher[]? Values)> KeyValueMatchers = [];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FormUrlEncodedMatcher"/> class.
|
||||
@@ -91,9 +91,10 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
{
|
||||
foreach (var nameValue in nameValueCollection)
|
||||
{
|
||||
var keyMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, [nameValue.Key], ignoreCase, MatchOperator);
|
||||
var valueMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, [nameValue.Value], ignoreCase, MatchOperator);
|
||||
_pairs.Add((keyMatcher, valueMatcher));
|
||||
var keyMatcher = new WildcardMatcher(MatchBehaviour.AcceptOnMatch, nameValue.Key, ignoreCase);
|
||||
var valueMatchers = nameValue.Value.Select(value => new WildcardMatcher(MatchBehaviour.AcceptOnMatch, value, ignoreCase)).ToArray();
|
||||
|
||||
KeyValueMatchers.Add((keyMatcher, valueMatchers));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,34 +120,48 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score));
|
||||
}
|
||||
|
||||
private bool[] GetMatches(IDictionary<string, string> inputNameValueCollection)
|
||||
private List<double> GetMatches(IDictionary<string, WireMockList<string>> inputNameValueCollection)
|
||||
{
|
||||
var matches = new List<bool>();
|
||||
if (_pairs.Count > inputNameValueCollection.Count)
|
||||
var inputPairs = inputNameValueCollection.ToArray();
|
||||
var rowCount = inputPairs.Length;
|
||||
var columnCount = KeyValueMatchers.Count;
|
||||
|
||||
if (rowCount == 0 && columnCount == 0)
|
||||
{
|
||||
matches.AddRange(Enumerable.Repeat(false, _pairs.Count - inputNameValueCollection.Count));
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach (var inputKeyValuePair in inputNameValueCollection)
|
||||
var matrix = new double[rowCount][];
|
||||
|
||||
for (var row = 0; row < rowCount; row++)
|
||||
{
|
||||
var match = false;
|
||||
foreach (var pair in _pairs)
|
||||
matrix[row] = new double[columnCount];
|
||||
|
||||
var inputKeyValuePair = inputPairs[row];
|
||||
var inputKey = inputKeyValuePair.Key;
|
||||
var inputValues = inputKeyValuePair.Value;
|
||||
|
||||
for (var column = 0; column < columnCount; column++)
|
||||
{
|
||||
var keyMatchResult = pair.Key.IsMatch(inputKeyValuePair.Key).IsPerfect();
|
||||
if (keyMatchResult)
|
||||
{
|
||||
match = pair.Value?.IsMatch(inputKeyValuePair.Value).IsPerfect() ?? false;
|
||||
if (match)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var (keyMatcher, valuesMatchers) = KeyValueMatchers[column];
|
||||
|
||||
matches.Add(match);
|
||||
var keyScore = keyMatcher.IsMatch(inputKey).Score;
|
||||
var valueScore = valuesMatchers != null ? MatchScores.ToScore(inputValues, valuesMatchers) : MatchScores.Perfect;
|
||||
|
||||
matrix[row][column] = Math.Min(keyScore, valueScore);
|
||||
}
|
||||
}
|
||||
|
||||
return matches.ToArray();
|
||||
var rowScores = rowCount == 0 ? [] : matrix.Select(row => row.Length == 0 ? MatchScores.Mismatch : row.Max()).ToList();
|
||||
|
||||
var columnScores = new List<double>();
|
||||
for (var column = 0; column < columnCount; column++)
|
||||
{
|
||||
columnScores.Add(rowCount == 0 ? MatchScores.Mismatch : matrix.Max(row => row[column]));
|
||||
}
|
||||
|
||||
rowScores.AddRange(columnScores);
|
||||
return rowScores;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -167,10 +182,10 @@ public class FormUrlEncodedMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(FormUrlEncodedMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] {{ {MappingConverterUtils.ToCSharpCodeArguments(_patterns)} }}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
|
||||
@@ -76,7 +76,7 @@ public class FuncMatcher : IFuncMatcher
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
var funcType = _stringFunc != null ? "Func<string?, bool>" : "Func<byte[]?, bool>";
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(FuncMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"/* {funcType} function */, " +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}" +
|
||||
|
||||
@@ -119,7 +119,7 @@ public class JsonPathMatcher : IJsonPathMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(JsonPathMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
|
||||
@@ -119,7 +119,7 @@ public class JmesPathMatcher : IStringMatcher, IObjectMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(JmesPathMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
|
||||
@@ -110,7 +110,7 @@ public class JsonMatcher : IJsonMatcher
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(JsonMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
|
||||
@@ -41,7 +41,7 @@ public class JsonPartialMatcher : AbstractJsonPartialMatcher
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(JsonPartialMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
|
||||
@@ -41,7 +41,7 @@ public class JsonPartialWildcardMatcher : AbstractJsonPartialMatcher
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(JsonPartialWildcardMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
|
||||
@@ -141,7 +141,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(LinqMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers.Helpers;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
@@ -34,7 +35,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// <summary>
|
||||
/// The body data function for FormUrlEncoded
|
||||
/// </summary>
|
||||
public Func<IDictionary<string, string>?, bool>? MatchOnBodyAsFormUrlEncodedFunc { get; }
|
||||
public Func<IDictionary<string, WireMockList<string>>?, bool>? MatchOnBodyAsFormUrlEncodedFunc { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
@@ -116,7 +117,7 @@ public class RequestMessageBodyMatcher : IRequestMatcher
|
||||
/// Initializes a new instance of the <see cref="RequestMessageBodyMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">The function.</param>
|
||||
public RequestMessageBodyMatcher(Func<IDictionary<string, string>?, bool> func)
|
||||
public RequestMessageBodyMatcher(Func<IDictionary<string, WireMockList<string>>?, bool> func)
|
||||
{
|
||||
MatchOnBodyAsFormUrlEncodedFunc = Guard.NotNull(func);
|
||||
}
|
||||
|
||||
@@ -115,36 +115,6 @@ public class RequestMessageParamMatcher : IRequestMatcher
|
||||
}
|
||||
|
||||
// Return the score based on Matchers and valuesPresentInRequestMessage
|
||||
return CalculateScore(Matchers, valuesPresentInRequestMessage);
|
||||
}
|
||||
|
||||
private static double CalculateScore(IReadOnlyList<IStringMatcher> matchers, WireMockList<string> valuesPresentInRequestMessage)
|
||||
{
|
||||
var total = new List<double>();
|
||||
|
||||
// If the total patterns in all matchers > values in message, use the matcher as base
|
||||
if (matchers.Sum(m => m.GetPatterns().Length) > valuesPresentInRequestMessage.Count)
|
||||
{
|
||||
foreach (var matcher in matchers)
|
||||
{
|
||||
double score = 0d;
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
score += matcher.IsMatch(valuePresentInRequestMessage).Score / matcher.GetPatterns().Length;
|
||||
}
|
||||
|
||||
total.Add(score);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (string valuePresentInRequestMessage in valuesPresentInRequestMessage)
|
||||
{
|
||||
var score = matchers.Max(m => m.IsMatch(valuePresentInRequestMessage).Score);
|
||||
total.Add(score);
|
||||
}
|
||||
}
|
||||
|
||||
return total.Any() ? MatchScores.ToScore(total, MatchOperator.Average) : 0;
|
||||
return MatchScores.ToScore(valuesPresentInRequestMessage, Matchers.ToArray());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using SimMetrics.Net;
|
||||
using SimMetrics.Net.API;
|
||||
@@ -92,10 +91,10 @@ public class SimMetricsMatcher : IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(SimMetricsMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] {{ {MappingConverterUtils.ToCSharpCodeArguments(_patterns)} }}, " +
|
||||
$"{_simMetricType.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
|
||||
@@ -115,7 +115,7 @@ public class SystemTextJsonMatcher : IJsonMatcher
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(SystemTextJsonMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
|
||||
@@ -41,7 +41,7 @@ public class SystemTextJsonPartialMatcher : AbstractSystemTextJsonPartialMatcher
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(SystemTextJsonPartialMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
|
||||
@@ -41,7 +41,7 @@ public class SystemTextJsonPartialWildcardMatcher : AbstractSystemTextJsonPartia
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(SystemTextJsonPartialWildcardMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{CSharpFormatter.ConvertToAnonymousObjectDefinition(Value, 3)}, " +
|
||||
|
||||
@@ -101,7 +101,7 @@ public class XPathMatcher : IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(XPathMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}, " +
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
using Stef.Validation;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
@@ -84,7 +85,7 @@ public partial class Request
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBody(Func<IDictionary<string, string>?, bool> func)
|
||||
public IRequestBuilder WithBody(Func<IDictionary<string, WireMockList<string>>?, bool> func)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(Guard.NotNull(func)));
|
||||
return this;
|
||||
|
||||
@@ -146,7 +146,7 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
|
||||
case JsonMatcher jsonMatcher:
|
||||
{
|
||||
var matcherType = jsonMatcher.GetType().Name;
|
||||
var matcherType = jsonMatcher.GetType().FullName;
|
||||
sb.AppendLine($" .WithBody(new {matcherType}(");
|
||||
sb.AppendLine($" value: {ConvertToAnonymousObjectDefinition(jsonMatcher.Value, 3)},");
|
||||
sb.AppendLine($" ignoreCase: {ToCSharpBooleanLiteral(jsonMatcher.IgnoreCase)},");
|
||||
@@ -162,14 +162,18 @@ internal class MappingConverter(MatcherMapper mapper)
|
||||
// Guid
|
||||
sb.AppendLine($" .WithGuid(\"{mapping.Guid}\")");
|
||||
|
||||
// Scenario + State
|
||||
// Scenario, ExecutionConditionState, NextState and StateTimes
|
||||
if (!string.IsNullOrEmpty(mapping.Scenario))
|
||||
{
|
||||
sb.AppendLine($" .InScenario({ToCSharpStringLiteral(mapping.Scenario)})");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(mapping.ExecutionConditionState))
|
||||
{
|
||||
sb.AppendLine($" .WhenStateIs({ToCSharpStringLiteral(mapping.ExecutionConditionState)})");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(mapping.NextState))
|
||||
{
|
||||
sb.AppendLine($" .WhenStateIs({ToCSharpStringLiteral(mapping.NextState)}, {ToCSharpIntLiteral(mapping.TimesInSameState)})");
|
||||
sb.AppendLine($" .WillSetStateTo({ToCSharpStringLiteral(mapping.NextState)}, {ToCSharpIntLiteral(mapping.TimesInSameState)})");
|
||||
}
|
||||
|
||||
if (mapping.Probability != null)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
namespace System.Collections.Generic;
|
||||
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
#if NETSTANDARD2_0
|
||||
public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue>? dictionary, TKey key, TValue value)
|
||||
{
|
||||
if (dictionary is null || dictionary.ContainsKey(key))
|
||||
@@ -16,5 +16,29 @@ internal static class DictionaryExtensions
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
public static bool TryGetFirstValue<TKey, TValue>(this IDictionary<TKey, TValue>? dictionary, out TValue? value)
|
||||
{
|
||||
if (dictionary != null && dictionary.Count > 0)
|
||||
{
|
||||
value = dictionary.First().Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryGetFirstOrDefault<TKey, TValue>(this IDictionary<TKey, TValue>? dictionary, out KeyValuePair<TKey, TValue> value)
|
||||
{
|
||||
if (dictionary != null && dictionary.Count > 0)
|
||||
{
|
||||
value = dictionary.First();
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
@@ -56,37 +54,25 @@ internal static class OpenApiSchemaExtensions
|
||||
|
||||
public static SchemaFormat GetSchemaFormat(this IOpenApiSchema? schema)
|
||||
{
|
||||
switch (schema?.Format)
|
||||
return (schema?.Format) switch
|
||||
{
|
||||
case "float":
|
||||
return SchemaFormat.Float;
|
||||
"float" => SchemaFormat.Float,
|
||||
"double" => SchemaFormat.Double,
|
||||
"int32" => SchemaFormat.Int32,
|
||||
"int64" => SchemaFormat.Int64,
|
||||
"date" => SchemaFormat.Date,
|
||||
"date-time" => SchemaFormat.DateTime,
|
||||
"password" => SchemaFormat.Password,
|
||||
"byte" => SchemaFormat.Byte,
|
||||
"binary" => SchemaFormat.Binary,
|
||||
_ => SchemaFormat.Undefined,
|
||||
};
|
||||
}
|
||||
|
||||
case "double":
|
||||
return SchemaFormat.Double;
|
||||
|
||||
case "int32":
|
||||
return SchemaFormat.Int32;
|
||||
|
||||
case "int64":
|
||||
return SchemaFormat.Int64;
|
||||
|
||||
case "date":
|
||||
return SchemaFormat.Date;
|
||||
|
||||
case "date-time":
|
||||
return SchemaFormat.DateTime;
|
||||
|
||||
case "password":
|
||||
return SchemaFormat.Password;
|
||||
|
||||
case "byte":
|
||||
return SchemaFormat.Byte;
|
||||
|
||||
case "binary":
|
||||
return SchemaFormat.Binary;
|
||||
|
||||
default:
|
||||
return SchemaFormat.Undefined;
|
||||
}
|
||||
internal static JsonNode? FindFirstExample(this IOpenApiSchema? schema)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
return schema?.Examples?.FirstOrDefault() ?? schema?.Example;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Stef.Validation;
|
||||
using WireMock.Net.OpenApiParser.Models;
|
||||
@@ -16,7 +14,8 @@ namespace WireMock.Net.OpenApiParser.Extensions;
|
||||
public static class WireMockServerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 file.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 file.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||
@@ -28,7 +27,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 file.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 file.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="path">Path containing OpenAPI file to parse and use the mappings.</param>
|
||||
@@ -46,7 +46,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 stream.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 stream.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||
@@ -58,7 +59,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 stream.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 stream.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="stream">Stream containing OpenAPI description to parse and use the mappings.</param>
|
||||
@@ -77,7 +79,8 @@ public static class WireMockServerExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1 document.
|
||||
/// Register the mappings via an OpenAPI (swagger) V2/V3/V3.1/V3.2 document.
|
||||
/// In case of an error, no mappings are registered and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="server">The WireMockServer instance</param>
|
||||
/// <param name="document">The OpenAPI document to use as mappings.</param>
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
<InputAssemblies Include="@(ReferencePathWithRefAssemblies)" Condition="'%(filename)' == 'Microsoft.OpenApi'" />
|
||||
<LibraryPath Include="%(ReferencePathWithRefAssemblies.RelativeDir)" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<DoNotInternalizeAssemblies Include="WireMock.Net.OpenApiParser" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ILRepack
|
||||
Parallel="true"
|
||||
Internalize="true"
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Net.OpenApiParser.Models;
|
||||
using WireMock.Net.OpenApiParser.Settings;
|
||||
@@ -15,6 +13,7 @@ public interface IWireMockOpenApiParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a file-path.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
@@ -23,6 +22,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a file-path.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to read the OpenApi/Swagger/V2/V3/V31 or Raml file.</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
@@ -40,6 +40,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
@@ -48,6 +49,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="Stream"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="stream">The source stream</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
@@ -57,6 +59,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="string"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="text">The source text</param>
|
||||
/// <param name="diagnostic">OpenApiDiagnostic output</param>
|
||||
@@ -65,6 +68,7 @@ public interface IWireMockOpenApiParser
|
||||
|
||||
/// <summary>
|
||||
/// Generate <see cref="IReadOnlyList{MappingModel}"/> from a <seealso cref="string"/>.
|
||||
/// In case of an error, an empty list is returned and <see cref="OpenApiDiagnostic"/> contains the error details.
|
||||
/// </summary>
|
||||
/// <param name="text">The source text</param>
|
||||
/// <param name="settings">Additional settings</param>
|
||||
|
||||
@@ -53,7 +53,7 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
Headers = MapRequestHeaders(requestHeaders),
|
||||
Body = GetRequestBodyModel(operation.RequestBody)
|
||||
},
|
||||
Response = GetResponseModel(operation.Responses?.FirstOrDefault())
|
||||
Response = operation.Responses?.TryGetFirstOrDefault(out var firstResponse) == true ? GetResponseModel(firstResponse) : new ResponseModel { StatusCode = 200 }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -70,8 +70,7 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
|
||||
var requestExample = requestContent?.Example;
|
||||
var requestExamples = requestContent?.Examples;
|
||||
var requestSchemaExample = requestContent?.Schema?.Example;
|
||||
var requestSchemaExamples = requestContent?.Schema?.Examples;
|
||||
var requestSchemaExample = requestContent?.Schema.FindFirstExample();
|
||||
|
||||
JsonNode? request;
|
||||
if (requestExample != null)
|
||||
@@ -86,10 +85,6 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
{
|
||||
request = requestExamples.FirstOrDefault().Value.Value;
|
||||
}
|
||||
else if (requestSchemaExamples != null)
|
||||
{
|
||||
request = requestSchemaExamples.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestSchema = content?.FirstOrDefault().Value.Schema;
|
||||
@@ -99,16 +94,15 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
return MapRequestBody(request) ?? new BodyModel();
|
||||
}
|
||||
|
||||
private ResponseModel GetResponseModel(KeyValuePair<string, IOpenApiResponse>? openApiResponse)
|
||||
private ResponseModel GetResponseModel(KeyValuePair<string, IOpenApiResponse> openApiResponse)
|
||||
{
|
||||
var content = openApiResponse?.Value.Content;
|
||||
var content = openApiResponse.Value.Content;
|
||||
|
||||
TryGetContent(content, out var responseContent, out var contentType);
|
||||
|
||||
var responseExample = responseContent?.Example;
|
||||
var responseExamples = responseContent?.Examples;
|
||||
var responseSchemaExample = responseContent?.Schema?.Example;
|
||||
var responseSchemaExamples = responseContent?.Schema?.Examples;
|
||||
var responseSchemaExample = responseContent?.Schema.FindFirstExample();
|
||||
|
||||
JsonNode? response;
|
||||
if (responseExample != null)
|
||||
@@ -119,24 +113,19 @@ internal class OpenApiPathsMapper(WireMockOpenApiParserSettings settings)
|
||||
{
|
||||
response = responseSchemaExample;
|
||||
}
|
||||
else if (responseExamples != null)
|
||||
else if (responseExamples.TryGetFirstValue(out var firstResponseFromExamples))
|
||||
{
|
||||
response = responseExamples.FirstOrDefault().Value.Value;
|
||||
}
|
||||
else if (responseSchemaExamples != null)
|
||||
{
|
||||
response = responseSchemaExamples.FirstOrDefault();
|
||||
response = firstResponseFromExamples?.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var responseSchema = content?.FirstOrDefault().Value?.Schema;
|
||||
response = MapSchemaToObject(responseSchema);
|
||||
response = content.TryGetFirstValue(out var firstContent) ? MapSchemaToObject(firstContent?.Schema) : null;
|
||||
}
|
||||
|
||||
return new ResponseModel
|
||||
{
|
||||
StatusCode = int.TryParse(openApiResponse?.Key, out var httpStatusCode) ? httpStatusCode : 200,
|
||||
Headers = MapHeaders(contentType, openApiResponse?.Value.Headers),
|
||||
StatusCode = int.TryParse(openApiResponse.Key, out var httpStatusCode) ? httpStatusCode : 200,
|
||||
Headers = MapHeaders(contentType, openApiResponse.Value.Headers),
|
||||
BodyAsJson = response != null ? JsonConvert.DeserializeObject(SystemTextJsonSerializer.Serialize(response)) : null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using RamlToOpenApiConverter;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Models;
|
||||
|
||||
/// <summary>
|
||||
@@ -24,5 +21,5 @@ public class OpenApiDiagnostic
|
||||
/// <summary>
|
||||
/// Open API specification version of the document parsed.
|
||||
/// </summary>
|
||||
public OpenApiSpecificationVersion SpecificationVersion { get; set; }
|
||||
public OpenApiSpecVersion SpecificationVersion { get; set; }
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Linq;
|
||||
using RamlToOpenApiConverter;
|
||||
using MicrosoftOpenApiDiagnostic = Microsoft.OpenApi.Reader.OpenApiDiagnostic;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Models;
|
||||
@@ -19,7 +17,7 @@ internal static class OpenApiMapper
|
||||
{
|
||||
Errors = openApiDiagnostic.Errors.Select(e => new OpenApiError(e.Pointer, e.Message)).ToList(),
|
||||
Warnings = openApiDiagnostic.Warnings.Select(e => new OpenApiError(e.Pointer, e.Message)).ToList(),
|
||||
SpecificationVersion = (OpenApiSpecificationVersion)openApiDiagnostic.SpecificationVersion
|
||||
SpecificationVersion = (OpenApiSpecVersion)openApiDiagnostic.SpecificationVersion
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Represents versions of OpenAPI specification.
|
||||
/// </summary>
|
||||
public enum OpenApiSpecVersion
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents OpenAPI V2.0 spec
|
||||
/// </summary>
|
||||
OpenApi2_0,
|
||||
|
||||
/// <summary>
|
||||
/// Represents all patches of OpenAPI V3.0 spec (e.g. 3.0.0, 3.0.1)
|
||||
/// </summary>
|
||||
OpenApi3_0,
|
||||
|
||||
/// <summary>
|
||||
/// Represents OpenAPI V3.1 spec
|
||||
/// </summary>
|
||||
OpenApi3_1,
|
||||
|
||||
/// <summary>
|
||||
/// Represents OpenAPI V3.2 spec
|
||||
/// </summary>
|
||||
OpenApi3_2
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Settings;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Microsoft.OpenApi;
|
||||
using RandomDataGenerator.FieldOptions;
|
||||
using RandomDataGenerator.Randomizers;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using Microsoft.OpenApi;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Settings;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace WireMock.Net.OpenApiParser.Utils;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.OpenApi;
|
||||
using Stef.Validation;
|
||||
@@ -39,7 +37,7 @@ internal class ExampleValueGenerator
|
||||
|
||||
public JsonNode GetExampleValue(IOpenApiSchema? schema)
|
||||
{
|
||||
var schemaExample = schema?.Example;
|
||||
var schemaExample = schema?.FindFirstExample();
|
||||
var schemaEnum = schema?.Enum?.FirstOrDefault();
|
||||
|
||||
_exampleValues.Schema = schema;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>An OpenApi (swagger) parser to generate MappingModel or mapping.json file.</Description>
|
||||
@@ -23,7 +23,7 @@
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Required" Version="1.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
@@ -40,25 +40,29 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="RamlToOpenApiConverter.SourceOnly" Version="0.21.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="18.1.0" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19.1" />
|
||||
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- https://github.com/wiremock/WireMock.Net/issues/1508 -->
|
||||
<ItemGroup>
|
||||
<PackageReference Include="RamlToOpenApiConverter.SourceOnly" Version="0.50.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" />
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.10.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<!-- Keep at version 2.0.43 (https://github.com/ravibpatel/ILRepack.Lib.MSBuild.Task/issues/80) -->
|
||||
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.43" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="3.7.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" PrivateAssets="All" />
|
||||
<PackageReference Include="SharpYaml" Version="2.1.4" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="3.10.2" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.10.2" PrivateAssets="All" />
|
||||
<PackageReference Include="SharpYaml" Version="2.1.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.OpenApi;
|
||||
@@ -18,7 +16,7 @@ using OpenApiDiagnostic = WireMock.Net.OpenApiParser.Models.OpenApiDiagnostic;
|
||||
namespace WireMock.Net.OpenApiParser;
|
||||
|
||||
/// <summary>
|
||||
/// Parse a OpenApi/Swagger/V2/V3/V3.1 to WireMock.Net MappingModels.
|
||||
/// Parse a OpenApi/Swagger/V2/V3/V3.1/V3.2 to WireMock.Net MappingModels.
|
||||
/// </summary>
|
||||
public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
{
|
||||
@@ -32,8 +30,15 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
_readerSettings = new OpenApiReaderSettings();
|
||||
_readerSettings.AddMicrosoftExtensionParsers();
|
||||
_readerSettings.AddJsonReader();
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yaml, new OpenApiYamlReader());
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yml, new OpenApiYamlReader());
|
||||
|
||||
var openApiYamlReaderSettings = new OpenApiYamlReaderSettings
|
||||
{
|
||||
MaxAliasExpansionNodeCount = 1_000_000
|
||||
};
|
||||
var openApiYamlReader = new OpenApiYamlReader(openApiYamlReaderSettings);
|
||||
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yaml, openApiYamlReader);
|
||||
_readerSettings.TryAddReader(OpenApiConstants.Yml, openApiYamlReader);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -55,7 +60,12 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
}
|
||||
else
|
||||
{
|
||||
document = Read(File.OpenRead(path), out diagnostic);
|
||||
if (!TryRead(File.OpenRead(path), out var documentFromYaml, out diagnostic))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
document = documentFromYaml;
|
||||
}
|
||||
|
||||
return FromDocument(document, settings);
|
||||
@@ -74,14 +84,24 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<MappingModel> FromStream(Stream stream, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return FromDocument(Read(stream, out diagnostic));
|
||||
if (TryRead(stream, out var openApiDocument, out diagnostic))
|
||||
{
|
||||
return FromDocument(openApiDocument);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<MappingModel> FromStream(Stream stream, WireMockOpenApiParserSettings settings, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
return FromDocument(Read(stream, out diagnostic), settings);
|
||||
if (TryRead(stream, out var openApiDocument, out diagnostic))
|
||||
{
|
||||
return FromDocument(openApiDocument, settings);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -98,7 +118,7 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
return FromStream(new MemoryStream(Encoding.UTF8.GetBytes(text)), settings, out diagnostic);
|
||||
}
|
||||
|
||||
private OpenApiDocument Read(Stream stream, out OpenApiDiagnostic diagnostic)
|
||||
private bool TryRead(Stream stream, [NotNullWhen(true)] out OpenApiDocument? openApiDocument, out OpenApiDiagnostic diagnostic)
|
||||
{
|
||||
if (stream is not MemoryStream memoryStream)
|
||||
{
|
||||
@@ -108,7 +128,8 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
var result = OpenApiDocument.Load(memoryStream, settings: _readerSettings);
|
||||
|
||||
diagnostic = OpenApiMapper.Map(result.Diagnostic) ?? new OpenApiDiagnostic();
|
||||
return result.Document ?? throw new InvalidOperationException("The document is null.");
|
||||
openApiDocument = result.Document;
|
||||
return openApiDocument != null && !diagnostic.Errors.Any();
|
||||
}
|
||||
|
||||
private static MemoryStream ReadStreamIntoMemoryStream(Stream stream)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using WireMock.Models;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
@@ -57,7 +55,7 @@ public static class MatchScores
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/>.</param>
|
||||
/// <returns>average score</returns>
|
||||
public static double ToScore(IReadOnlyCollection<bool> values, MatchOperator matchOperator)
|
||||
public static double ToScore(IReadOnlyList<bool> values, MatchOperator matchOperator)
|
||||
{
|
||||
return ToScore(values.Select(ToScore).ToArray(), matchOperator);
|
||||
}
|
||||
@@ -68,9 +66,9 @@ public static class MatchScores
|
||||
/// <param name="values">The values.</param>
|
||||
/// <param name="matchOperator"></param>
|
||||
/// <returns>average score</returns>
|
||||
public static double ToScore(IReadOnlyCollection<double> values, MatchOperator matchOperator)
|
||||
public static double ToScore(IReadOnlyList<double> values, MatchOperator matchOperator)
|
||||
{
|
||||
if (!values.Any())
|
||||
if (values.Count == 0)
|
||||
{
|
||||
return Mismatch;
|
||||
}
|
||||
@@ -82,4 +80,28 @@ public static class MatchScores
|
||||
_ => values.Average()
|
||||
};
|
||||
}
|
||||
|
||||
internal static double ToScore(WireMockList<string> values, IStringMatcher[] matchers, MatchOperator matchOperator = MatchOperator.And)
|
||||
{
|
||||
// Create a matrix of scores where each row corresponds to a value and each column corresponds to a matcher.
|
||||
var matrix = values
|
||||
.Select(value => matchers
|
||||
.Select(matcher => matcher.IsMatch(value).Score).ToArray()
|
||||
)
|
||||
.ToArray();
|
||||
|
||||
if (matrix.Length == 0 || matchers.Length == 0)
|
||||
{
|
||||
return Mismatch;
|
||||
}
|
||||
|
||||
// For each value, how well was it matched by its best matcher?
|
||||
var rowScore = matchOperator == MatchOperator.And ? matrix.Average(row => row.Max()) : matrix.Max(row => row.Max());
|
||||
|
||||
// For each matcher, how well was it satisfied by its best value?
|
||||
var columnRange = Enumerable.Range(0, matchers.Length);
|
||||
var columnScore = matchOperator == MatchOperator.And ? columnRange.Average(column => matrix.Max(row => row[column])) : columnRange.Max(column => matrix.Max(row => row[column]));
|
||||
|
||||
return matchOperator == MatchOperator.And ? Math.Min(rowScore, columnScore) : Math.Max(rowScore, columnScore);
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class NotNullOrEmptyMatcher : IObjectMatcher, IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(NotNullOrEmptyMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AnyOfTypes;
|
||||
using JetBrains.Annotations;
|
||||
@@ -132,10 +130,10 @@ public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher
|
||||
/// <inheritdoc />
|
||||
public virtual string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(RegexMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] {{ {MappingConverterUtils.ToCSharpCodeArguments(_patterns)} }}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(_useRegexExtended)}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using AnyOfTypes;
|
||||
using Stef.Validation;
|
||||
@@ -74,10 +73,10 @@ public class WildcardMatcher : RegexMatcher
|
||||
/// <inheritdoc />
|
||||
public override string GetCSharpCodeArguments()
|
||||
{
|
||||
return $"new {Name}" +
|
||||
return $"new {typeof(WildcardMatcher).FullName}" +
|
||||
$"(" +
|
||||
$"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " +
|
||||
$"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " +
|
||||
$"new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] {{ {MappingConverterUtils.ToCSharpCodeArguments(_patterns)} }}, " +
|
||||
$"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " +
|
||||
$"{MatchOperator.GetFullyQualifiedEnumValue()}" +
|
||||
$")";
|
||||
|
||||
@@ -22,7 +22,7 @@ public class BodyData : IBodyData
|
||||
public string? BodyAsString { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDictionary<string, string>? BodyAsFormUrlEncoded { get; set; }
|
||||
public IDictionary<string, WireMockList<string>>? BodyAsFormUrlEncoded { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public object? BodyAsJson { get; set; }
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
@@ -100,5 +99,5 @@ public interface IBodyRequestBuilder : IMultiPartRequestBuilder
|
||||
/// </summary>
|
||||
/// <param name="func">The form-urlencoded values.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<IDictionary<string, string>?, bool> func);
|
||||
IRequestBuilder WithBody(Func<IDictionary<string, WireMockList<string>>?, bool> func);
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using WireMock.Types;
|
||||
|
||||
@@ -16,7 +13,7 @@ internal static class QueryStringParser
|
||||
{
|
||||
private static readonly Dictionary<string, WireMockList<string>> Empty = new();
|
||||
|
||||
public static bool TryParse(string? queryString, bool caseIgnore, [NotNullWhen(true)] out IDictionary<string, string>? nameValueCollection)
|
||||
public static bool TryParse(string? queryString, bool caseIgnore, [NotNullWhen(true)] out IDictionary<string, WireMockList<string>>? nameValueCollection)
|
||||
{
|
||||
if (queryString == null)
|
||||
{
|
||||
@@ -29,12 +26,22 @@ internal static class QueryStringParser
|
||||
.Select(parameter => parameter.Split('='))
|
||||
.Distinct();
|
||||
|
||||
nameValueCollection = caseIgnore ? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) : new Dictionary<string, string>();
|
||||
nameValueCollection = caseIgnore ? new Dictionary<string, WireMockList<string>>(StringComparer.OrdinalIgnoreCase) : new Dictionary<string, WireMockList<string>>();
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (part.Length == 2)
|
||||
{
|
||||
nameValueCollection.Add(part[0], WebUtility.UrlDecode(part[1]));
|
||||
var key = part[0];
|
||||
var value = WebUtility.UrlDecode(part[1]);
|
||||
|
||||
if (!nameValueCollection.TryGetValue(key, out var stringList))
|
||||
{
|
||||
nameValueCollection.Add(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringList.Add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -408,4 +408,210 @@ public class WireMockListTests
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equality Operator Tests
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_EqualityOperator_ListToSingleValue_WhenSingleElementMatchesValue_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
(list == "hello").Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_EqualityOperator_ListToSingleValue_WhenSingleElementDoesNotMatchValue_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
(list == "world").Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_EqualityOperator_ListToSingleValue_WhenMultipleElements_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello", "world");
|
||||
|
||||
// Act & Assert
|
||||
(list == "hello").Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_EqualityOperator_SingleValueToList_WhenSingleElementMatchesValue_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
("hello" == list).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_EqualityOperator_SingleValueToList_WhenSingleElementDoesNotMatchValue_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
("world" == list).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_InequalityOperator_ListToSingleValue_WhenSingleElementMatchesValue_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
(list != "hello").Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_InequalityOperator_ListToSingleValue_WhenSingleElementDoesNotMatchValue_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
(list != "world").Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_InequalityOperator_SingleValueToList_WhenSingleElementMatchesValue_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
("hello" != list).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_InequalityOperator_SingleValueToList_WhenSingleElementDoesNotMatchValue_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("hello");
|
||||
|
||||
// Act & Assert
|
||||
("world" != list).Should().BeTrue();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Equals and GetHashCode Tests
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenBothListsHaveSameElements_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>("a", "b", "c");
|
||||
var list2 = new WireMockList<string>("a", "b", "c");
|
||||
|
||||
// Act & Assert
|
||||
list1.Equals(list2).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenListsHaveDifferentElements_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>("a", "b");
|
||||
var list2 = new WireMockList<string>("a", "x");
|
||||
|
||||
// Act & Assert
|
||||
list1.Equals(list2).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenListsHaveDifferentCounts_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>("a", "b");
|
||||
var list2 = new WireMockList<string>("a");
|
||||
|
||||
// Act & Assert
|
||||
list1.Equals(list2).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenBothEmpty_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>();
|
||||
var list2 = new WireMockList<string>();
|
||||
|
||||
// Act & Assert
|
||||
list1.Equals(list2).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenSameReference_ShouldBeTrue()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("a", "b");
|
||||
var sameReference = list;
|
||||
|
||||
// Act & Assert
|
||||
list.Equals(sameReference).Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenComparedToNull_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("a");
|
||||
|
||||
// Act & Assert
|
||||
list.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_Equals_WhenComparedToNonWireMockList_ShouldBeFalse()
|
||||
{
|
||||
// Arrange
|
||||
var list = new WireMockList<string>("a");
|
||||
|
||||
// Act & Assert
|
||||
list.Equals(new List<string> { "a" }).Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_GetHashCode_WhenListsHaveSameElements_ShouldBeEqual()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>("a", "b", "c");
|
||||
var list2 = new WireMockList<string>("a", "b", "c");
|
||||
|
||||
// Act & Assert
|
||||
list1.GetHashCode().Should().Be(list2.GetHashCode());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_GetHashCode_WhenListsHaveDifferentElements_ShouldNotBeEqual()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>("a", "b");
|
||||
var list2 = new WireMockList<string>("x", "y");
|
||||
|
||||
// Act & Assert
|
||||
list1.GetHashCode().Should().NotBe(list2.GetHashCode());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockListOfString_GetHashCode_WhenEmpty_ShouldReturnConsistentValue()
|
||||
{
|
||||
// Arrange
|
||||
var list1 = new WireMockList<string>();
|
||||
var list2 = new WireMockList<string>();
|
||||
|
||||
// Act & Assert
|
||||
list1.GetHashCode().Should().Be(list2.GetHashCode());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
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"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/foo1" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("p1", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "xyz"))
|
||||
)
|
||||
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
|
||||
.RespondWith(Response.Create()
|
||||
|
||||
+9
-9
@@ -2,8 +2,8 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new JsonPartialMatcher(
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/users/post2" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new WireMock.Matchers.JsonPartialMatcher(
|
||||
value: new
|
||||
{
|
||||
city = "City",
|
||||
@@ -22,8 +22,8 @@ Some ""value"" in Line2")
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo2", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("p2", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "abc"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/foo2" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("p2", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "abc"))
|
||||
.WithHeader("h1", "W/\"234f2q3r\"", true)
|
||||
)
|
||||
.WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd")
|
||||
@@ -37,8 +37,8 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new JsonMatcher(
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/users/post1" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new WireMock.Matchers.JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
city = "Amsterdam",
|
||||
@@ -55,7 +55,7 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("DELETE")
|
||||
.WithUrl(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "https://localhost/test", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithUrl(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "https://localhost/test" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("c9929240-7ae8-4a5d-8ed8-0913479f6eeb")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -99,8 +99,8 @@ 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"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/foo1" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("p1", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "xyz"))
|
||||
)
|
||||
.WithGuid("f74fd144-df53-404f-8e35-da22a640bd5f")
|
||||
.RespondWith(Response.Create()
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("test", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, "abc"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/foo" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("test", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, "abc"))
|
||||
)
|
||||
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -13,8 +13,8 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new JsonMatcher(
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/users/post1" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new WireMock.Matchers.JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
Request = "Hello?"
|
||||
@@ -30,8 +30,8 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new JsonMatcher(
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/users/post2" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new WireMock.Matchers.JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
city = "Amsterdam",
|
||||
@@ -48,7 +48,7 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/form-urlencoded", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/form-urlencoded" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
|
||||
.WithBody("name=John Doe")
|
||||
)
|
||||
@@ -59,8 +59,8 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/regex", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("foo", new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, ".*", false, true, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/regex" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("foo", new WireMock.Matchers.RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { ".*" }, false, true, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931004")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -69,11 +69,11 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/todo/items", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/todo/items" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931005")
|
||||
.InScenario("To do list")
|
||||
.WhenStateIs("TodoList State Started", 2)
|
||||
.WillSetStateTo("TodoList State Started", 2)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("Buy milk")
|
||||
);
|
||||
@@ -81,7 +81,7 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/delay", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/delay" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931006")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -91,7 +91,7 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/random-delay", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/random-delay" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931007")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -101,7 +101,7 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/prob", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/prob" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931008")
|
||||
.WithProbability(0.1)
|
||||
@@ -112,7 +112,7 @@ builder
|
||||
builder
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/prob", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/prob" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931009")
|
||||
.WithProbability(0.9)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/foo", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("test", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, "abc"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/foo" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("test", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, "abc"))
|
||||
)
|
||||
.WithGuid("41372914-1838-4c67-916b-b9aacdd096ce")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -13,8 +13,8 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post1", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new JsonMatcher(
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/users/post1" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new WireMock.Matchers.JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
Request = "Hello?"
|
||||
@@ -30,8 +30,8 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/users/post2", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new JsonMatcher(
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/users/post2" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithBody(new WireMock.Matchers.JsonMatcher(
|
||||
value: new
|
||||
{
|
||||
city = "Amsterdam",
|
||||
@@ -48,7 +48,7 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("POST")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/form-urlencoded", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/form-urlencoded" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithHeader("Content-Type", "application/x-www-form-urlencoded", true)
|
||||
.WithBody("name=John Doe")
|
||||
)
|
||||
@@ -59,8 +59,8 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/regex", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("foo", new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, ".*", false, true, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/regex" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("foo", new WireMock.Matchers.RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { ".*" }, false, true, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931004")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -69,11 +69,11 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/todo/items", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/todo/items" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931005")
|
||||
.InScenario("To do list")
|
||||
.WhenStateIs("TodoList State Started", 2)
|
||||
.WillSetStateTo("TodoList State Started", 2)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("Buy milk")
|
||||
);
|
||||
@@ -81,7 +81,7 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/delay", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/delay" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931006")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -91,7 +91,7 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/random-delay", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/random-delay" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931007")
|
||||
.RespondWith(Response.Create()
|
||||
@@ -101,7 +101,7 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/prob", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/prob" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931008")
|
||||
.WithProbability(0.1)
|
||||
@@ -112,7 +112,7 @@ server
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/prob", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/prob" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("98fae52e-76df-47d9-876f-2ee32e931009")
|
||||
.WithProbability(0.9)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using System.Net.Http;
|
||||
using AnyOfTypes;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Net.Tests.Matchers;
|
||||
|
||||
@@ -12,59 +11,155 @@ public class FormUrlEncodedMatcherTest
|
||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
[Theory]
|
||||
[InlineData("*=*")]
|
||||
[InlineData("name=John Doe")]
|
||||
[InlineData("name=*")]
|
||||
[InlineData("*=John Doe")]
|
||||
[InlineData("email=johndoe@example.com")]
|
||||
[InlineData("email=*")]
|
||||
[InlineData("*=johndoe@example.com")]
|
||||
[InlineData("name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData("name=John Doe", "email=*")]
|
||||
[InlineData("name=*", "email=*")]
|
||||
[InlineData("*=John Doe", "*=johndoe@example.com")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch(params string[] patterns)
|
||||
[InlineData(true, "*=*")]
|
||||
[InlineData(true, "name=John Doe")]
|
||||
[InlineData(false, "name=Stef")]
|
||||
[InlineData(false, "name=John Doe&name=Stef")]
|
||||
[InlineData(true, "name=*")]
|
||||
[InlineData(true, "*=John Doe")]
|
||||
[InlineData(false, "*=Stef")]
|
||||
[InlineData(false, "*=John Doe&*=Stef")]
|
||||
[InlineData(true, "email=johndoe@example.com")]
|
||||
[InlineData(true, "email=*")]
|
||||
[InlineData(true, "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=*")]
|
||||
[InlineData(true, "name=John Doe&name=Stef", "email=*")]
|
||||
[InlineData(true, "name=Stef", "email=*")]
|
||||
[InlineData(true, "name=*", "email=*")]
|
||||
[InlineData(true, "*=John Doe", "*=johndoe@example.com")]
|
||||
[InlineData(true, "*=Stef", "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe&name=Stef", "*=johndoe@example.com")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_Single_Or(bool expected, params string[] patterns)
|
||||
{
|
||||
// Arrange
|
||||
var content = new FormUrlEncodedContent(
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
]);
|
||||
var contentAsString = await content.ReadAsStringAsync(_ct);
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.Select(p => new AnyOf<string, StringPattern>(p)).ToArray());
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.ToAnyOfPatterns());
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
|
||||
// Assert
|
||||
score.Should().BeTrue();
|
||||
score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "*=*")]
|
||||
[InlineData(false, "name=John Doe")]
|
||||
[InlineData(false, "name=Stef")]
|
||||
[InlineData(true, "name=John Doe&name=Stef")]
|
||||
[InlineData(true, "name=*")]
|
||||
[InlineData(false, "*=John Doe")]
|
||||
[InlineData(false, "*=Stef")]
|
||||
[InlineData(true, "*=John Doe&*=Stef")]
|
||||
[InlineData(true, "email=johndoe@example.com")]
|
||||
[InlineData(true, "email=*")]
|
||||
[InlineData(true, "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=*")]
|
||||
[InlineData(true, "name=John Doe&name=Stef", "email=*")]
|
||||
[InlineData(true, "name=Stef", "email=*")]
|
||||
[InlineData(true, "name=*", "email=*")]
|
||||
[InlineData(true, "*=John Doe", "*=johndoe@example.com")]
|
||||
[InlineData(true, "*=Stef", "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe&name=Stef", "*=johndoe@example.com")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_Multiple_Or(bool expected, params string[] patterns)
|
||||
{
|
||||
// Arrange
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("name", "Stef"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
]);
|
||||
var contentAsString = await content.ReadAsStringAsync(_ct);
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.ToAnyOfPatterns());
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
|
||||
// Assert
|
||||
score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "*=*")]
|
||||
[InlineData(false, "name=John Doe")]
|
||||
[InlineData(false, "name=Stef")]
|
||||
[InlineData(false, "name=John Doe&name=Stef")]
|
||||
[InlineData(false, "name=*")]
|
||||
[InlineData(false, "*=John Doe")]
|
||||
[InlineData(false, "*=Stef")]
|
||||
[InlineData(false, "*=John Doe&*=Stef")]
|
||||
[InlineData(false, "email=johndoe@example.com")]
|
||||
[InlineData(false, "email=*")]
|
||||
[InlineData(false, "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe", "email=*")]
|
||||
[InlineData(false, "name=John Doe&name=Stef", "email=*")]
|
||||
[InlineData(false, "name=Stef", "email=*")]
|
||||
[InlineData(true, "name=*", "email=*")]
|
||||
[InlineData(true, "*=John Doe", "*=johndoe@example.com")]
|
||||
[InlineData(true, "*=*")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_And(bool expected, params string[] patterns)
|
||||
[InlineData(false, "*=Stef", "*=johndoe@example.com")]
|
||||
[InlineData(false, "name=John Doe&name=Stef", "*=johndoe@example.com")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_Single_And(bool expected, params string[] patterns)
|
||||
{
|
||||
// Arrange
|
||||
var content = new FormUrlEncodedContent(
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
]);
|
||||
var contentAsString = await content.ReadAsStringAsync(_ct);
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.Select(p => new AnyOf<string, StringPattern>(p)).ToArray(), true, MatchOperator.And);
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.ToAnyOfPatterns(), true, MatchOperator.And);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
|
||||
// Assert
|
||||
score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true, "*=*")]
|
||||
[InlineData(false, "name=John Doe")]
|
||||
[InlineData(false, "name=Stef")]
|
||||
[InlineData(false, "name=John Doe&name=Stef")]
|
||||
[InlineData(false, "name=*")]
|
||||
[InlineData(false, "*=John Doe")]
|
||||
[InlineData(false, "*=Stef")]
|
||||
[InlineData(false, "*=John Doe&*=Stef")]
|
||||
[InlineData(false, "email=johndoe@example.com")]
|
||||
[InlineData(false, "email=*")]
|
||||
[InlineData(false, "*=johndoe@example.com")]
|
||||
[InlineData(false, "name=John Doe", "email=johndoe@example.com")]
|
||||
[InlineData(false, "name=John Doe", "email=*")]
|
||||
[InlineData(true, "name=John Doe&name=Stef", "email=*")]
|
||||
[InlineData(false, "name=Stef", "email=*")]
|
||||
[InlineData(true, "name=*", "email=*")]
|
||||
[InlineData(false, "*=John Doe", "*=johndoe@example.com")]
|
||||
[InlineData(false, "*=Stef", "*=johndoe@example.com")]
|
||||
[InlineData(true, "name=John Doe&name=Stef", "*=johndoe@example.com")]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_Multiple_And(bool expected, params string[] patterns)
|
||||
{
|
||||
// Arrange
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("name", "Stef"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
]);
|
||||
var contentAsString = await content.ReadAsStringAsync(_ct);
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(patterns.ToAnyOfPatterns(), true, MatchOperator.And);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
@@ -74,12 +169,13 @@ public class FormUrlEncodedMatcherTest
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_And_MatchAllProperties()
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_And_MatchAllProperties_MissingRequiredKey_ShouldNotMatch()
|
||||
{
|
||||
// Arrange
|
||||
var content = new FormUrlEncodedContent(
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("name", "Stef"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
]);
|
||||
var contentAsString = await content.ReadAsStringAsync(_ct);
|
||||
@@ -93,4 +189,25 @@ public class FormUrlEncodedMatcherTest
|
||||
// Assert
|
||||
score.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FormUrlEncodedMatcher_IsMatch_And_MatchAllProperties_ConflictingEmailPatterns_ShouldNotMatch()
|
||||
{
|
||||
// Arrange
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("name", "Stef"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
]);
|
||||
var contentAsString = await content.ReadAsStringAsync(_ct);
|
||||
|
||||
var matcher = new FormUrlEncodedMatcher(["name=*", "email=*", "email=x"], matchOperator: MatchOperator.And);
|
||||
|
||||
// Act
|
||||
var score = matcher.IsMatch(contentAsString).IsPerfect();
|
||||
|
||||
// Assert
|
||||
score.Should().BeFalse();
|
||||
}
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public class FuncMatcherTests
|
||||
var code = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
code.Should().Be("new FuncMatcher(/* Func<string?, bool> function */, WireMock.Matchers.MatchBehaviour.AcceptOnMatch)");
|
||||
code.Should().Be("new WireMock.Matchers.FuncMatcher(/* Func<string?, bool> function */, WireMock.Matchers.MatchBehaviour.AcceptOnMatch)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -271,7 +271,7 @@ public class FuncMatcherTests
|
||||
var code = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
code.Should().Be("new FuncMatcher(/* Func<byte[]?, bool> function */, WireMock.Matchers.MatchBehaviour.AcceptOnMatch)");
|
||||
code.Should().Be("new WireMock.Matchers.FuncMatcher(/* Func<byte[]?, bool> function */, WireMock.Matchers.MatchBehaviour.AcceptOnMatch)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -667,7 +667,7 @@ public class JsonMatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().StartWith($"new JsonMatcher(WireMock.Matchers.MatchBehaviour.{matchBehaviour},");
|
||||
result.Should().StartWith($"new WireMock.Matchers.JsonMatcher(WireMock.Matchers.MatchBehaviour.{matchBehaviour},");
|
||||
result.Should().EndWith($", {ignoreCase.ToString().ToLowerInvariant()}, {regex.ToString().ToLowerInvariant()}, {ignoreArrayOrder.ToString().ToLowerInvariant()})");
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new ContentTypeMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"application/json\", false)");
|
||||
result.Should().Be("new WireMock.Matchers.ContentTypeMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { \"application/json\" }, false)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -27,7 +27,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, \"test\")");
|
||||
result.Should().Be("new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.Or, \"test\")");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -53,7 +53,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new FormUrlEncodedMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"key=value\", false, WireMock.Matchers.MatchOperator.Or)");
|
||||
result.Should().Be("new WireMock.Matchers.FormUrlEncodedMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { \"key=value\" }, false, WireMock.Matchers.MatchOperator.Or)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -66,7 +66,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new JmesPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"expression\")");
|
||||
result.Should().Be("new WireMock.Matchers.JmesPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"expression\")");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -79,7 +79,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().StartWith("new JsonMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
|
||||
result.Should().StartWith("new WireMock.Matchers.JsonMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -92,7 +92,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().StartWith("new JsonPartialMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
|
||||
result.Should().StartWith("new WireMock.Matchers.JsonPartialMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -105,7 +105,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().StartWith("new JsonPartialWildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
|
||||
result.Should().StartWith("new WireMock.Matchers.JsonPartialWildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch,");
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
@@ -118,7 +118,7 @@ public class MatcherTests
|
||||
// var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// // Assert
|
||||
// result.Should().Be("new LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"it.Contains(\\\"test\\\"\")");
|
||||
// result.Should().Be("new WireMock.Matchers.LinqMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, \"it.Contains(\\\"test\\\"\")");
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
@@ -131,7 +131,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"pattern\", false, true, WireMock.Matchers.MatchOperator.Or)");
|
||||
result.Should().Be("new WireMock.Matchers.RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { \"pattern\" }, false, true, WireMock.Matchers.MatchOperator.Or)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -144,7 +144,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new SimMetricsMatcher.Levenstein(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"test\", SimMetrics.Net.SimMetricType.Levenstein, WireMock.Matchers.MatchOperator.Average)");
|
||||
result.Should().Be("new WireMock.Matchers.SimMetricsMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { \"test\" }, SimMetrics.Net.SimMetricType.Levenstein, WireMock.Matchers.MatchOperator.Average)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -157,7 +157,7 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, \"pattern\", false, WireMock.Matchers.MatchOperator.Or)");
|
||||
result.Should().Be("new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { \"pattern\" }, false, WireMock.Matchers.MatchOperator.Or)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -170,6 +170,6 @@ public class MatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().Be("new XPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, null, \"pattern1\")");
|
||||
result.Should().Be("new WireMock.Matchers.XPathMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, WireMock.Matchers.MatchOperator.Or, null, \"pattern1\")");
|
||||
}
|
||||
}
|
||||
@@ -478,7 +478,7 @@ public class SystemTextJsonMatcherTests
|
||||
var result = matcher.GetCSharpCodeArguments();
|
||||
|
||||
// Assert
|
||||
result.Should().StartWith($"new SystemTextJsonMatcher(WireMock.Matchers.MatchBehaviour.{matchBehaviour},");
|
||||
result.Should().StartWith($"new WireMock.Matchers.SystemTextJsonMatcher(WireMock.Matchers.MatchBehaviour.{matchBehaviour},");
|
||||
result.Should().EndWith($", {ignoreCase.ToString().ToLowerInvariant()}, {regex.ToString().ToLowerInvariant()}, {ignoreArrayOrder.ToString().ToLowerInvariant()})");
|
||||
}
|
||||
}
|
||||
@@ -36,12 +36,38 @@ public class WireMockOpenApiParserTests
|
||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "payroc-openapi-spec.yaml"));
|
||||
|
||||
// Act
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out _);
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out var diagnostic);
|
||||
|
||||
// Assert
|
||||
mappings.Should().NotBeEmpty();
|
||||
diagnostic.Should().NotBeNull();
|
||||
diagnostic.Errors.Should().BeEmpty();
|
||||
|
||||
// Verify
|
||||
await Verify(mappings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FromText_UsingInvalidYaml_ShouldReturnEmptyMappingsWithDiagnostic()
|
||||
{
|
||||
// Arrange
|
||||
var settings = new WireMockOpenApiParserSettings
|
||||
{
|
||||
ExampleValues = _exampleValuesMock.Object
|
||||
};
|
||||
|
||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "invalid.yaml"));
|
||||
|
||||
// Act
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out var diagnostic);
|
||||
|
||||
// Assert
|
||||
mappings.Should().BeEmpty();
|
||||
diagnostic.Should().NotBeNull();
|
||||
diagnostic.Errors.Should().HaveCount(1);
|
||||
diagnostic.Errors[0].Message.Should().Be("Responses must contain at least one response");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FromText_UsingJson_WithPlainTextExample_ShouldReturnMappings()
|
||||
{
|
||||
@@ -54,7 +80,12 @@ public class WireMockOpenApiParserTests
|
||||
var openApiDocument = File.ReadAllText(Path.Combine("OpenApiParser", "oas-content-example.json"));
|
||||
|
||||
// Act
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out _);
|
||||
var mappings = _sut.FromText(openApiDocument, settings, out var diagnostic);
|
||||
|
||||
// Assert
|
||||
mappings.Should().NotBeEmpty();
|
||||
diagnostic.Should().NotBeNull();
|
||||
diagnostic.Errors.Should().BeEmpty();
|
||||
|
||||
// Verify
|
||||
await Verify(mappings);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
openapi: 3.2.0
|
||||
info:
|
||||
version: '1'
|
||||
title: Invalid API
|
||||
description: Invalid
|
||||
|
||||
paths:
|
||||
/funding-recipients:
|
||||
summary: Create and manage funding recipients.
|
||||
post:
|
||||
tags:
|
||||
- Funding recipients
|
||||
@@ -142,12 +142,12 @@ public class RequestBuilderWithBodyTests
|
||||
public void Request_WithBody_FuncFormUrlEncoded()
|
||||
{
|
||||
// Assign
|
||||
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IDictionary<string, string>? values) => values != null);
|
||||
var requestBuilder = Request.Create().UsingAnyMethod().WithBody((IDictionary<string, WireMockList<string>>? values) => values != null);
|
||||
|
||||
// Act
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsFormUrlEncoded = new Dictionary<string, string>(),
|
||||
BodyAsFormUrlEncoded = new Dictionary<string, WireMockList<string>>(),
|
||||
DetectedBodyTypeFromContentType = BodyType.FormUrlEncoded,
|
||||
DetectedBodyType = BodyType.FormUrlEncoded
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test1"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "KeY", true, new[] { "test1" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "KeY", true, ["test1"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -30,7 +30,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test1"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new[] { "test1", "test2" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, ["test1", "test2"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -60,7 +60,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test1,test2,test3"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new IStringMatcher[] { new ExactMatcher("test1", "test2") });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, [new ExactMatcher("test1", "test2")]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -71,18 +71,18 @@ public class RequestMessageParamMatcherTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestMessageParamMatcher_GetMatchingScore_KeyWith2ValuesPresentInUrl_And_With1ExactStringWith3Patterns_Returns0_66()
|
||||
public void RequestMessageParamMatcher_GetMatchingScore_KeyWith2ValuesPresentInUrl_And_With1ExactStringWith3Patterns_Returns1_0()
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test1,test2"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new IStringMatcher[] { new ExactMatcher("test1", "test2", "test3") });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, [new ExactMatcher("test1", "test2", "test3")]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
score.Should().BeApproximately(0.66d, 0.1d);
|
||||
score.Should().Be(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -90,7 +90,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test1,test2"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new[] { "test1", "test2" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, ["test1", "test2"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -105,7 +105,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test1,test2"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new IStringMatcher[] { new ExactMatcher("test1"), new ExactMatcher("test2") });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, [new ExactMatcher("test1"), new ExactMatcher("test2")]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -120,7 +120,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=test0,test2"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new[] { "test1", "test2" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, ["test1", "test2"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -135,7 +135,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new[] { "test1", "test2" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, ["test1", "test2"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -215,7 +215,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign: the param value in the URL matches the reject pattern -> the mapping must be rejected (score 0.0).
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=abc"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.RejectOnMatch, "key", false, new[] { "abc" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.RejectOnMatch, "key", false, ["abc"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -230,7 +230,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign: the param value in the URL does NOT match the reject pattern -> the mapping is accepted (score 1.0).
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=xyz"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.RejectOnMatch, "key", false, new[] { "abc" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.RejectOnMatch, "key", false, ["abc"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -245,7 +245,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign: ignoreCase must still be honored on the inner matcher after the fix.
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=ABC"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.RejectOnMatch, "key", true, new[] { "abc" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.RejectOnMatch, "key", true, ["abc"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -260,7 +260,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=abc"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new[] { "abc" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, ["abc"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
@@ -275,7 +275,7 @@ public class RequestMessageParamMatcherTests
|
||||
{
|
||||
// Assign
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost?key=xyz"), "GET", "127.0.0.1");
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, new[] { "abc" });
|
||||
var matcher = new RequestMessageParamMatcher(MatchBehaviour.AcceptOnMatch, "key", false, ["abc"]);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright © WireMock.Net
|
||||
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Net.Tests.VerifyExtensions;
|
||||
using WireMock.RequestBuilders;
|
||||
@@ -97,6 +98,167 @@ public partial class MappingConverterTests
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToCSharpCode_With_ScenarioAndState_Emits_WhenStateIs_And_WillSetStateTo()
|
||||
{
|
||||
// Assign: a stateful mapping that gates on state "Begin" and moves to "End" after 3 hits.
|
||||
var mapping = CreateScenarioMapping("Ordering", executionConditionState: "Begin", nextState: "End", timesInSameState: 3);
|
||||
|
||||
// Act
|
||||
var code = _sut.ToCSharpCode(mapping, new MappingConverterSettings
|
||||
{
|
||||
AddStart = false,
|
||||
ConverterType = MappingConverterType.Server
|
||||
});
|
||||
|
||||
// Verify
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToCSharpCode_With_NextStateOnly_Emits_WillSetStateTo_Without_Times()
|
||||
{
|
||||
// Assign: a start-state mapping that only sets the next state (no execution condition, default times).
|
||||
var mapping = CreateScenarioMapping("Ordering", executionConditionState: null, nextState: "Begin", timesInSameState: null);
|
||||
|
||||
// Act
|
||||
var code = _sut.ToCSharpCode(mapping, new MappingConverterSettings
|
||||
{
|
||||
AddStart = false,
|
||||
ConverterType = MappingConverterType.Server
|
||||
});
|
||||
|
||||
// Verify
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToCSharpCode_WithPath_RegexMatcher_MultiplePatterns()
|
||||
{
|
||||
// Assign
|
||||
var mapping = CreateMappingWithRequest(Request.Create()
|
||||
.UsingGet()
|
||||
.WithPath(new RegexMatcher(MatchBehaviour.AcceptOnMatch, ["/a", "/b"])));
|
||||
|
||||
// Act
|
||||
var code = _sut.ToCSharpCode(mapping, new MappingConverterSettings
|
||||
{
|
||||
AddStart = false,
|
||||
ConverterType = MappingConverterType.Server
|
||||
});
|
||||
|
||||
// Verify
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToCSharpCode_WithPath_SimMetricsMatcher_MultiplePatterns()
|
||||
{
|
||||
// Assign
|
||||
var mapping = CreateMappingWithRequest(Request.Create()
|
||||
.UsingGet()
|
||||
.WithPath(new SimMetricsMatcher(new AnyOfTypes.AnyOf<string, Models.StringPattern>[] { "/a", "/b" })));
|
||||
|
||||
// Act
|
||||
var code = _sut.ToCSharpCode(mapping, new MappingConverterSettings
|
||||
{
|
||||
AddStart = false,
|
||||
ConverterType = MappingConverterType.Server
|
||||
});
|
||||
|
||||
// Verify
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToCSharpCode_WithPath_ContentTypeMatcher_MultiplePatterns()
|
||||
{
|
||||
// Assign
|
||||
var mapping = CreateMappingWithRequest(Request.Create()
|
||||
.UsingGet()
|
||||
.WithPath(new ContentTypeMatcher(["text/a", "text/b"])));
|
||||
|
||||
// Act
|
||||
var code = _sut.ToCSharpCode(mapping, new MappingConverterSettings
|
||||
{
|
||||
AddStart = false,
|
||||
ConverterType = MappingConverterType.Server
|
||||
});
|
||||
|
||||
// Verify
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToCSharpCode_WithPath_FormUrlEncodedMatcher_MultiplePatterns()
|
||||
{
|
||||
// Assign
|
||||
var mapping = CreateMappingWithRequest(Request.Create()
|
||||
.UsingGet()
|
||||
.WithPath(new FormUrlEncodedMatcher(["a=1", "b=2"])));
|
||||
|
||||
// Act
|
||||
var code = _sut.ToCSharpCode(mapping, new MappingConverterSettings
|
||||
{
|
||||
AddStart = false,
|
||||
ConverterType = MappingConverterType.Server
|
||||
});
|
||||
|
||||
// Verify
|
||||
return Verify(code, VerifySettings);
|
||||
}
|
||||
|
||||
private Mapping CreateMappingWithRequest(IRequestBuilder requestBuilder)
|
||||
{
|
||||
return new Mapping
|
||||
(
|
||||
guid: new Guid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc"),
|
||||
updatedAt: _updatedAt,
|
||||
title: string.Empty,
|
||||
description: string.Empty,
|
||||
path: null,
|
||||
settings: _settings,
|
||||
requestMatcher: (IRequestMatcher)requestBuilder,
|
||||
provider: Response.Create().WithSuccess(),
|
||||
priority: 0,
|
||||
scenario: null,
|
||||
executionConditionState: null,
|
||||
nextState: null,
|
||||
stateTimes: null,
|
||||
webhooks: null,
|
||||
useWebhooksFireAndForget: false,
|
||||
timeSettings: null,
|
||||
data: null
|
||||
);
|
||||
}
|
||||
|
||||
private Mapping CreateScenarioMapping(string scenario, string? executionConditionState, string? nextState, int? timesInSameState)
|
||||
{
|
||||
var request = Request.Create().UsingGet().WithPath("/test_path");
|
||||
var response = Response.Create().WithSuccess();
|
||||
|
||||
return new Mapping
|
||||
(
|
||||
guid: new Guid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc"),
|
||||
updatedAt: _updatedAt,
|
||||
title: string.Empty,
|
||||
description: string.Empty,
|
||||
path: null,
|
||||
settings: _settings,
|
||||
requestMatcher: request,
|
||||
provider: response,
|
||||
priority: 0,
|
||||
scenario: scenario,
|
||||
executionConditionState: executionConditionState,
|
||||
nextState: nextState,
|
||||
stateTimes: timesInSameState,
|
||||
webhooks: null,
|
||||
useWebhooksFireAndForget: false,
|
||||
timeSettings: null,
|
||||
data: null
|
||||
);
|
||||
}
|
||||
|
||||
private IMapping CreateMapping()
|
||||
{
|
||||
var guid = new Guid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc");
|
||||
@@ -117,22 +279,22 @@ public partial class MappingConverterTests
|
||||
|
||||
return new Mapping
|
||||
(
|
||||
guid,
|
||||
_updatedAt,
|
||||
string.Empty,
|
||||
string.Empty,
|
||||
null,
|
||||
_settings,
|
||||
request,
|
||||
response,
|
||||
42,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
guid: guid,
|
||||
updatedAt: _updatedAt,
|
||||
title: string.Empty,
|
||||
description: string.Empty,
|
||||
path: null,
|
||||
settings: _settings,
|
||||
requestMatcher: request,
|
||||
provider: response,
|
||||
priority: 42,
|
||||
scenario: null,
|
||||
executionConditionState: null,
|
||||
nextState: null,
|
||||
stateTimes: null,
|
||||
webhooks: null,
|
||||
useWebhooksFireAndForget: false,
|
||||
timeSettings: null,
|
||||
data: null
|
||||
).WithProbability(0.3);
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WireMock.Matchers.ContentTypeMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "text/a", "text/b" }, false))
|
||||
)
|
||||
.WithGuid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc")
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
);
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WireMock.Matchers.FormUrlEncodedMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "a=1", "b=2" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc")
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
);
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WireMock.Matchers.RegexMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/a", "/b" }, false, true, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc")
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
);
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WireMock.Matchers.SimMetricsMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/a", "/b" }, SimMetrics.Net.SimMetricType.Levenstein, WireMock.Matchers.MatchOperator.Average))
|
||||
)
|
||||
.WithGuid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc")
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
);
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
.Given(Request.Create()
|
||||
.WithEarlyMismatch(WireMock.Matchers.Request.RequestMatcherType.Method)
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/test_path", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/test_path" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithClientIP("112.123.100.99")
|
||||
.WithHeader("h-key", "h-value", true)
|
||||
.WithCookie("c-key", "c-value", true)
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ builder
|
||||
.Given(Request.Create()
|
||||
.WithEarlyMismatch(WireMock.Matchers.Request.RequestMatcherType.Method)
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/test_path", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/test_path" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithClientIP("112.123.100.99")
|
||||
.WithHeader("h-key", "h-value", true)
|
||||
.WithCookie("c-key", "c-value", true)
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/test_path" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc")
|
||||
.InScenario("Ordering")
|
||||
.WillSetStateTo("Begin", null)
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
);
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/test_path" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
)
|
||||
.WithGuid("8e7b9ab7-e18e-4502-8bc9-11e6679811cc")
|
||||
.InScenario("Ordering")
|
||||
.WhenStateIs("Begin")
|
||||
.WillSetStateTo("End", 3)
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
);
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
.Given(Request.Create()
|
||||
.WithEarlyMismatch(WireMock.Matchers.Request.RequestMatcherType.Method)
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/test_path", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/test_path" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithClientIP("112.123.100.99")
|
||||
.WithHeader("h-key", "h-value", true)
|
||||
.WithCookie("c-key", "c-value", true)
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ server
|
||||
.Given(Request.Create()
|
||||
.WithEarlyMismatch(WireMock.Matchers.Request.RequestMatcherType.Method)
|
||||
.UsingMethod("GET")
|
||||
.WithPath(new WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, "/test_path", false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithPath(new WireMock.Matchers.WildcardMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, new AnyOfTypes.AnyOf<string, WireMock.Models.StringPattern>[] { "/test_path" }, false, WireMock.Matchers.MatchOperator.Or))
|
||||
.WithParam("q", new WireMock.Matchers.ExactMatcher(WireMock.Matchers.MatchBehaviour.AcceptOnMatch, false, WireMock.Matchers.MatchOperator.And, "42"))
|
||||
.WithClientIP("112.123.100.99")
|
||||
.WithHeader("h-key", "h-value", true)
|
||||
.WithCookie("c-key", "c-value", true)
|
||||
|
||||
@@ -7,27 +7,27 @@ namespace WireMock.Net.Tests.Util;
|
||||
|
||||
public class QueryStringParserTests
|
||||
{
|
||||
public static IEnumerable<object?[]> QueryStringTestData => new List<object?[]>
|
||||
public static List<object?[]> QueryStringTestData => new()
|
||||
{
|
||||
new object?[] { null, false, false, null },
|
||||
new object?[] { string.Empty, false, true, new Dictionary<string, string>() },
|
||||
new object?[] { "test", false, true, new Dictionary<string, string>() },
|
||||
new object?[] { "&", false, true, new Dictionary<string, string>() },
|
||||
new object?[] { "&&", false, true, new Dictionary<string, string>() },
|
||||
new object?[] { "a=", false, true, new Dictionary<string, string> { { "a", "" } } },
|
||||
new object?[] { "&a", false, true, new Dictionary<string, string>() },
|
||||
new object?[] { "&a=", false, true, new Dictionary<string, string> { { "a", "" } } },
|
||||
new object?[] { "&key1=value1", false, true, new Dictionary<string, string> { { "key1", "value1" } } },
|
||||
new object?[] { "key1=value1", false, true, new Dictionary<string, string> { { "key1", "value1" } } },
|
||||
new object?[] { "key1=value1&key2=value2", false, true, new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } } },
|
||||
new object?[] { "key1=value1&key2=value2&", false, true, new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } } },
|
||||
new object?[] { "key1=value1&&key2=value2", false, true, new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } } },
|
||||
new object?[] { "&key1=value1&key2=value2&&", false, true, new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } } },
|
||||
new object?[] { string.Empty, false, true, new Dictionary<string, WireMockList<string>>() },
|
||||
new object?[] { "test", false, true, new Dictionary<string, WireMockList<string>>() },
|
||||
new object?[] { "&", false, true, new Dictionary<string, WireMockList<string>>() },
|
||||
new object?[] { "&&", false, true, new Dictionary<string, WireMockList<string>>() },
|
||||
new object?[] { "a=", false, true, new Dictionary<string, WireMockList<string>> { { "a", new WireMockList<string>("") } } },
|
||||
new object?[] { "&a", false, true, new Dictionary<string, WireMockList<string>>() },
|
||||
new object?[] { "&a=", false, true, new Dictionary<string, WireMockList<string>> { { "a", new WireMockList<string>("") } } },
|
||||
new object?[] { "&key1=value1", false, true, new Dictionary<string, WireMockList<string>> { { "key1", new WireMockList<string>("value1") } } },
|
||||
new object?[] { "key1=value1", false, true, new Dictionary<string, WireMockList<string>> { { "key1", new WireMockList<string>("value1") } } },
|
||||
new object?[] { "key1=value1&key2=value2", false, true, new Dictionary<string, WireMockList<string>> { { "key1", new WireMockList<string>("value1") }, { "key2", new WireMockList<string>("value2") } } },
|
||||
new object?[] { "key1=value1&key2=value2&", false, true, new Dictionary<string, WireMockList<string>> { { "key1", new WireMockList<string>("value1") }, { "key2", new WireMockList<string>("value2") } } },
|
||||
new object?[] { "key1=value1&&key2=value2", false, true, new Dictionary<string, WireMockList<string>> { { "key1", new WireMockList<string>("value1") }, { "key2", new WireMockList<string>("value2") } } },
|
||||
new object?[] { "&key1=value1&key2=value2&&", false, true, new Dictionary<string, WireMockList<string>> { { "key1", new WireMockList<string>("value1") }, { "key2", new WireMockList<string>("value2") } } },
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(QueryStringTestData))]
|
||||
public void TryParse_Should_Parse_QueryString(string queryString, bool caseIgnore, bool expectedResult, IDictionary<string, string> expectedOutput)
|
||||
public void TryParse_Should_Parse_QueryString(string queryString, bool caseIgnore, bool expectedResult, IDictionary<string, WireMockList<string>> expectedOutput)
|
||||
{
|
||||
// Act
|
||||
var result = QueryStringParser.TryParse(queryString, caseIgnore, out var actual);
|
||||
@@ -49,7 +49,7 @@ public class QueryStringParserTests
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
actual.Should().BeEquivalentTo(new Dictionary<string, string> { { "x", "rNaCP7hv8UOmS/JcujdvLw==" } });
|
||||
actual.Should().BeEquivalentTo(new Dictionary<string, WireMockList<string>> { { "x", new WireMockList<string>("rNaCP7hv8UOmS/JcujdvLw==") } });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -12,6 +12,7 @@ using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Net.Tests;
|
||||
|
||||
@@ -339,7 +340,7 @@ public partial class WireMockServerTests
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFunc()
|
||||
public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFunc1()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.Start();
|
||||
@@ -354,8 +355,36 @@ public partial class WireMockServerTests
|
||||
);
|
||||
|
||||
// Act
|
||||
var content = new FormUrlEncodedContent([new KeyValuePair<string, string>("key1", "value1")]);
|
||||
var response = await new HttpClient()
|
||||
using var content = new FormUrlEncodedContent([new KeyValuePair<string, string>("key1", "value1")]);
|
||||
using var httpClient = new HttpClient();
|
||||
var response = await httpClient
|
||||
.PostAsync($"{server.Url}/foo", content, _ct);
|
||||
|
||||
// Assert
|
||||
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFunc2()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.Start();
|
||||
server.Given(
|
||||
Request.Create()
|
||||
.UsingPost()
|
||||
.WithPath("/foo")
|
||||
.WithBody((IDictionary<string, WireMockList<string>>? values) => values != null && values.TryGetValue("key1", out var v) && v == "value1")
|
||||
)
|
||||
.RespondWith(
|
||||
Response.Create()
|
||||
);
|
||||
|
||||
// Act
|
||||
using var content = new FormUrlEncodedContent([new KeyValuePair<string, string>("key1", "value1")]);
|
||||
using var httpClient = new HttpClient();
|
||||
var response = await httpClient
|
||||
.PostAsync($"{server.Url}/foo", content, _ct);
|
||||
|
||||
// Assert
|
||||
@@ -382,7 +411,7 @@ public partial class WireMockServerTests
|
||||
);
|
||||
|
||||
// Act
|
||||
var content = new FormUrlEncodedContent(
|
||||
using var content = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
@@ -400,7 +429,7 @@ public partial class WireMockServerTests
|
||||
public async Task WireMockServer_WithBodyAsFormUrlEncoded_Using_PostAsync_And_WithFormUrlEncodedMatcher()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new FormUrlEncodedMatcher(["email=johndoe@example.com", "name=John Doe"]);
|
||||
var matcher = new FormUrlEncodedMatcher(["email=johndoe@example.com", "name=John*"]);
|
||||
using var server = WireMockServer.Start();
|
||||
server.Given(
|
||||
Request.Create()
|
||||
@@ -425,7 +454,7 @@ public partial class WireMockServerTests
|
||||
);
|
||||
|
||||
// Act 1
|
||||
var contentOrdered = new FormUrlEncodedContent(
|
||||
using var contentOrdered = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com")
|
||||
@@ -439,7 +468,7 @@ public partial class WireMockServerTests
|
||||
|
||||
|
||||
// Act 2
|
||||
var contentUnordered = new FormUrlEncodedContent(
|
||||
using var contentUnordered = new FormUrlEncodedContent(
|
||||
[
|
||||
new KeyValuePair<string, string>("email", "johndoe@example.com"),
|
||||
new KeyValuePair<string, string>("name", "John Doe"),
|
||||
@@ -447,7 +476,6 @@ public partial class WireMockServerTests
|
||||
var responseUnordered = await new HttpClient()
|
||||
.PostAsync($"{server.Url}/bar", contentUnordered, _ct)
|
||||
;
|
||||
|
||||
// Assert 2
|
||||
responseUnordered.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
|
||||
Reference in new issue
Block a user