mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
Add WireMock.org RestClient (#631)
* wip... * x * . * . * . * r * 1.4.21-preview-02 * 1.4.21-preview-03 * . * usings * wip * . * ut * . * . * . * tests * . * comments * readme
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.4.20</VersionPrefix>
|
||||
<VersionPrefix>1.4.21-preview-04</VersionPrefix>
|
||||
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
|
||||
<PackageIconUrl>https://raw.githubusercontent.com/WireMock-Net/WireMock.Net/master/WireMock.Net-Logo.png</PackageIconUrl>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
|
||||
@@ -34,9 +34,11 @@ For more info, see also this WIKI page: [What is WireMock.Net](https://github.co
|
||||
| **WireMock.Net** | [](https://www.nuget.org/packages/WireMock.Net) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net)
|
||||
| **WireMock.Net.StandAlone** | [](https://www.nuget.org/packages/WireMock.Net.StandAlone) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.StandAlone)
|
||||
| **WireMock.Net.FluentAssertions** | [](https://www.nuget.org/packages/WireMock.Net.FluentAssertions) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.FluentAssertions)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Net.Matchers.CSharpCode** | [](https://www.nuget.org/packages/WireMock.Net.Matchers.CSharpCode) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.Matchers.CSharpCode)
|
||||
| **WireMock.Net.OpenApiParser** | [](https://www.nuget.org/packages/WireMock.Net.OpenApiParser) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.OpenApiParser)
|
||||
| **WireMock.Net.RestClient** | [](https://www.nuget.org/packages/WireMock.Net.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Net.RestClient)
|
||||
| **WireMock.Org.RestClient** | [](https://www.nuget.org/packages/WireMock.Org.RestClient) | [](https://www.myget.org/feed/wiremock-net/package/nuget/WireMock.Org.RestClient)
|
||||
|
||||
|
||||
## Development
|
||||
For the supported frameworks and build information, see [this](https://github.com/WireMock-Net/WireMock.Net/wiki/Development-Information) page.
|
||||
|
||||
@@ -92,6 +92,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Azure Pipelines", "Azure Pi
|
||||
azure-pipelines-nuget.yml = azure-pipelines-nuget.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Org.RestClient", "src\WireMock.Org.RestClient\WireMock.Org.RestClient.csproj", "{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Org.Abstractions", "src\WireMock.Org.Abstractions\WireMock.Org.Abstractions.csproj", "{3BA5109E-5F30-4CC2-B699-02EC82560AA6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -214,6 +218,14 @@ Global
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3BA5109E-5F30-4CC2-B699-02EC82560AA6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -250,6 +262,8 @@ Global
|
||||
{6580580B-1EFD-4922-B0EC-FF290DB279EE} = {985E0ADB-D4B4-473A-AA40-567E279B7946}
|
||||
{1DAEFF47-D117-4E95-8B3E-4F7C8B92011A} = {7EFB2C5B-1BB2-4AAF-BC9F-216ED80C594D}
|
||||
{5B64F6CA-BF6B-4F67-BB2A-9C47E441703E} = {7EFB2C5B-1BB2-4AAF-BC9F-216ED80C594D}
|
||||
{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
{3BA5109E-5F30-4CC2-B699-02EC82560AA6} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="RestEase" Version="1.4.10" />
|
||||
<PackageReference Include="RestEase" Version="1.5.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -204,8 +204,8 @@
|
||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="RestEase, Version=1.4.10.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RestEase.1.4.10\lib\net45\RestEase.dll</HintPath>
|
||||
<Reference Include="RestEase, Version=1.5.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\RestEase.1.5.5\lib\net45\RestEase.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimMetrics.Net, Version=1.0.5.0, Culture=neutral, PublicKeyToken=c58dc06d59f3391b, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\SimMetrics.Net.1.0.5\lib\net45\SimMetrics.Net.dll</HintPath>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<package id="MimeKitLite" version="2.0.7" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />
|
||||
<package id="Owin" version="1.0" targetFramework="net461" />
|
||||
<package id="RestEase" version="1.4.10" targetFramework="net461" />
|
||||
<package id="RestEase" version="1.5.5" targetFramework="net461" />
|
||||
<package id="SimMetrics.Net" version="1.0.5" targetFramework="net461" />
|
||||
<package id="System.Buffers" version="4.5.0" targetFramework="net461" />
|
||||
<package id="System.Collections.Immutable" version="1.5.0" targetFramework="net461" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Commonly used interfaces, models, enumerations and types.</Description>
|
||||
<Description>Commonly used models, enumerations and types.</Description>
|
||||
<AssemblyTitle>WireMock.Net.Abstractions</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net45;netstandard1.0;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<AssemblyName>WireMock.Net.Abstractions</AssemblyName>
|
||||
<PackageId>WireMock.Net.Abstractions</PackageId>
|
||||
<PackageTags>wiremock;interfaces;models;classes;enumerations;types</PackageTags>
|
||||
<PackageTags>wiremock;wiremock.org;interfaces;models;classes;enumerations;types</PackageTags>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
<ProjectGuid>{B6269AAC-170A-4346-8B9A-579DED3D9A94}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
@@ -33,11 +33,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2020.1.0" PrivateAssets="All" />
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
|
||||
<!-- See also https://mstack.nl/blog/20210801-source-generators -->
|
||||
<PackageReference Include="FluentBuilder" Version="0.0.7">
|
||||
<PackageReference Include="FluentBuilder" Version="0.0.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>A RestClient using RestEase to access the admin interface.</Description>
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="RestEase" Version="1.4.10" />
|
||||
<PackageReference Include="RestEase" Version="1.5.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,167 +1,167 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using SimMetrics.Net;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Matchers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using SimMetrics.Net;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Plugin;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Serialization
|
||||
{
|
||||
internal class MatcherMapper
|
||||
{
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
|
||||
public MatcherMapper(IWireMockServerSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public IMatcher[] Map([CanBeNull] IEnumerable<MatcherModel> matchers)
|
||||
{
|
||||
return matchers?.Select(Map).Where(m => m != null).ToArray();
|
||||
}
|
||||
|
||||
public IMatcher Map([CanBeNull] MatcherModel matcher)
|
||||
{
|
||||
if (matcher == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] parts = matcher.Name.Split('.');
|
||||
string matcherName = parts[0];
|
||||
string matcherType = parts.Length > 1 ? parts[1] : null;
|
||||
|
||||
string[] stringPatterns = (matcher.Patterns != null ? matcher.Patterns : new[] { matcher.Pattern }).OfType<string>().ToArray();
|
||||
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
||||
bool ignoreCase = matcher.IgnoreCase == true;
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
|
||||
switch (matcherName)
|
||||
using WireMock.Settings;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Serialization
|
||||
{
|
||||
internal class MatcherMapper
|
||||
{
|
||||
private readonly IWireMockServerSettings _settings;
|
||||
|
||||
public MatcherMapper(IWireMockServerSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public IMatcher[] Map([CanBeNull] IEnumerable<MatcherModel> matchers)
|
||||
{
|
||||
return matchers?.Select(Map).Where(m => m != null).ToArray();
|
||||
}
|
||||
|
||||
public IMatcher Map([CanBeNull] MatcherModel matcher)
|
||||
{
|
||||
if (matcher == null)
|
||||
{
|
||||
case "NotNullOrEmptyMatcher":
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] parts = matcher.Name.Split('.');
|
||||
string matcherName = parts[0];
|
||||
string matcherType = parts.Length > 1 ? parts[1] : null;
|
||||
|
||||
string[] stringPatterns = (matcher.Patterns != null ? matcher.Patterns : new[] { matcher.Pattern }).OfType<string>().ToArray();
|
||||
MatchBehaviour matchBehaviour = matcher.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch;
|
||||
bool ignoreCase = matcher.IgnoreCase == true;
|
||||
bool throwExceptionWhenMatcherFails = _settings.ThrowExceptionWhenMatcherFails == true;
|
||||
|
||||
switch (matcherName)
|
||||
{
|
||||
case "NotNullOrEmptyMatcher":
|
||||
return new NotNullOrEmptyMatcher(matchBehaviour);
|
||||
|
||||
case "CSharpCodeMatcher":
|
||||
if (_settings.AllowCSharpCodeMatcher == true)
|
||||
{
|
||||
return PluginLoader.Load<ICSharpCodeMatcher>(matchBehaviour, stringPatterns);
|
||||
}
|
||||
|
||||
throw new NotSupportedException("It's not allowed to use the 'CSharpCodeMatcher' because IWireMockServerSettings.AllowCSharpCodeMatcher is not set to 'true'.");
|
||||
|
||||
case "LinqMatcher":
|
||||
return new LinqMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "ExactMatcher":
|
||||
return new ExactMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "ExactObjectMatcher":
|
||||
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
|
||||
|
||||
case "RegexMatcher":
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "JsonMatcher":
|
||||
object value = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonMatcher(matchBehaviour, value, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "JsonPartialMatcher":
|
||||
object matcherValue = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonPartialMatcher(matchBehaviour, matcherValue, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "JsonPathMatcher":
|
||||
return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "JmesPathMatcher":
|
||||
return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "XPathMatcher":
|
||||
return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "WildcardMatcher":
|
||||
return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "ContentTypeMatcher":
|
||||
return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "SimMetricsMatcher":
|
||||
SimMetricType type = SimMetricType.Levenstein;
|
||||
if (!string.IsNullOrEmpty(matcherType) && !Enum.TryParse(matcherType, out type))
|
||||
{
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||
}
|
||||
|
||||
return new SimMetricsMatcher(matchBehaviour, stringPatterns, type, throwExceptionWhenMatcherFails);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
|
||||
{
|
||||
return matchers?.Select(Map).Where(m => m != null).ToArray();
|
||||
}
|
||||
|
||||
public MatcherModel Map([CanBeNull] IMatcher matcher)
|
||||
{
|
||||
if (matcher == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
object[] patterns = new object[0]; // Default empty array
|
||||
switch (matcher)
|
||||
{
|
||||
// If the matcher is a IStringMatcher, get the patterns.
|
||||
case IStringMatcher stringMatcher:
|
||||
patterns = stringMatcher.GetPatterns().Cast<object>().ToArray();
|
||||
break;
|
||||
|
||||
// If the matcher is a IValueMatcher, get the value (can be string or object).
|
||||
case IValueMatcher valueMatcher:
|
||||
patterns = new[] { valueMatcher.Value };
|
||||
break;
|
||||
|
||||
// If the matcher is a ExactObjectMatcher, get the ValueAsObject or ValueAsBytes.
|
||||
case ExactObjectMatcher exactObjectMatcher:
|
||||
patterns = new[] { exactObjectMatcher.ValueAsObject ?? exactObjectMatcher.ValueAsBytes };
|
||||
break;
|
||||
}
|
||||
|
||||
bool? ignoreCase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : (bool?)null;
|
||||
|
||||
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : (bool?)null;
|
||||
|
||||
return new MatcherModel
|
||||
{
|
||||
RejectOnMatch = rejectOnMatch,
|
||||
IgnoreCase = ignoreCase,
|
||||
Name = matcher.Name,
|
||||
Pattern = patterns.Length == 1 ? patterns.First() : null,
|
||||
Patterns = patterns.Length > 1 ? patterns : null
|
||||
};
|
||||
}
|
||||
|
||||
private ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, string stringPattern, bool throwException)
|
||||
{
|
||||
byte[] bytePattern;
|
||||
try
|
||||
{
|
||||
bytePattern = Convert.FromBase64String(stringPattern);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentException($"Matcher 'ExactObjectMatcher' has invalid pattern. The pattern value '{stringPattern}' is not a Base64String.", nameof(stringPattern));
|
||||
}
|
||||
|
||||
return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException);
|
||||
}
|
||||
}
|
||||
|
||||
case "CSharpCodeMatcher":
|
||||
if (_settings.AllowCSharpCodeMatcher == true)
|
||||
{
|
||||
return PluginLoader.Load<ICSharpCodeMatcher>(matchBehaviour, stringPatterns);
|
||||
}
|
||||
|
||||
throw new NotSupportedException("It's not allowed to use the 'CSharpCodeMatcher' because IWireMockServerSettings.AllowCSharpCodeMatcher is not set to 'true'.");
|
||||
|
||||
case "LinqMatcher":
|
||||
return new LinqMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "ExactMatcher":
|
||||
return new ExactMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "ExactObjectMatcher":
|
||||
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
|
||||
|
||||
case "RegexMatcher":
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "JsonMatcher":
|
||||
object value = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonMatcher(matchBehaviour, value, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "JsonPartialMatcher":
|
||||
object matcherValue = matcher.Pattern ?? matcher.Patterns;
|
||||
return new JsonPartialMatcher(matchBehaviour, matcherValue, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "JsonPathMatcher":
|
||||
return new JsonPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "JmesPathMatcher":
|
||||
return new JmesPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "XPathMatcher":
|
||||
return new XPathMatcher(matchBehaviour, throwExceptionWhenMatcherFails, stringPatterns);
|
||||
|
||||
case "WildcardMatcher":
|
||||
return new WildcardMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "ContentTypeMatcher":
|
||||
return new ContentTypeMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails);
|
||||
|
||||
case "SimMetricsMatcher":
|
||||
SimMetricType type = SimMetricType.Levenstein;
|
||||
if (!string.IsNullOrEmpty(matcherType) && !Enum.TryParse(matcherType, out type))
|
||||
{
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' with Type '{matcherType}' is not supported.");
|
||||
}
|
||||
|
||||
return new SimMetricsMatcher(matchBehaviour, stringPatterns, type, throwExceptionWhenMatcherFails);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Matcher '{matcherName}' is not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
public MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
|
||||
{
|
||||
return matchers?.Select(Map).Where(m => m != null).ToArray();
|
||||
}
|
||||
|
||||
public MatcherModel Map([CanBeNull] IMatcher matcher)
|
||||
{
|
||||
if (matcher == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
object[] patterns = new object[0]; // Default empty array
|
||||
switch (matcher)
|
||||
{
|
||||
// If the matcher is a IStringMatcher, get the patterns.
|
||||
case IStringMatcher stringMatcher:
|
||||
patterns = stringMatcher.GetPatterns().Cast<object>().ToArray();
|
||||
break;
|
||||
|
||||
// If the matcher is a IValueMatcher, get the value (can be string or object).
|
||||
case IValueMatcher valueMatcher:
|
||||
patterns = new[] { valueMatcher.Value };
|
||||
break;
|
||||
|
||||
// If the matcher is a ExactObjectMatcher, get the ValueAsObject or ValueAsBytes.
|
||||
case ExactObjectMatcher exactObjectMatcher:
|
||||
patterns = new[] { exactObjectMatcher.ValueAsObject ?? exactObjectMatcher.ValueAsBytes };
|
||||
break;
|
||||
}
|
||||
|
||||
bool? ignoreCase = matcher is IIgnoreCaseMatcher ignoreCaseMatcher ? ignoreCaseMatcher.IgnoreCase : (bool?)null;
|
||||
|
||||
bool? rejectOnMatch = matcher.MatchBehaviour == MatchBehaviour.RejectOnMatch ? true : (bool?)null;
|
||||
|
||||
return new MatcherModel
|
||||
{
|
||||
RejectOnMatch = rejectOnMatch,
|
||||
IgnoreCase = ignoreCase,
|
||||
Name = matcher.Name,
|
||||
Pattern = patterns.Length == 1 ? patterns.First() : null,
|
||||
Patterns = patterns.Length > 1 ? patterns : null
|
||||
};
|
||||
}
|
||||
|
||||
private ExactObjectMatcher CreateExactObjectMatcher(MatchBehaviour matchBehaviour, string stringPattern, bool throwException)
|
||||
{
|
||||
byte[] bytePattern;
|
||||
try
|
||||
{
|
||||
bytePattern = Convert.FromBase64String(stringPattern);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new ArgumentException($"Matcher 'ExactObjectMatcher' has invalid pattern. The pattern value '{stringPattern}' is not a Base64String.", nameof(stringPattern));
|
||||
}
|
||||
|
||||
return new ExactObjectMatcher(matchBehaviour, bytePattern, throwException);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ namespace WireMock.Server
|
||||
private const string ContentTypeJson = "application/json";
|
||||
private const string AdminFiles = "/__admin/files";
|
||||
private const string AdminMappings = "/__admin/mappings";
|
||||
private const string AdminMappingsWireMockOrg = "/__admin/mappings/wiremock.org";
|
||||
private const string AdminRequests = "/__admin/requests";
|
||||
private const string AdminSettings = "/__admin/settings";
|
||||
private const string AdminScenarios = "/__admin/scenarios";
|
||||
@@ -58,6 +59,7 @@ namespace WireMock.Server
|
||||
// __admin/mappings
|
||||
Given(Request.Create().WithPath(AdminMappings).UsingGet()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsGet));
|
||||
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, _adminRequestContentTypeJson)).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPost));
|
||||
Given(Request.Create().WithPath(AdminMappingsWireMockOrg).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, _adminRequestContentTypeJson)).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPostWireMockOrg));
|
||||
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
|
||||
|
||||
// __admin/mappings/reset
|
||||
|
||||
306
src/WireMock.Net/Server/WireMockServer.ImportWireMockOrg.cs
Normal file
306
src/WireMock.Net/Server/WireMockServer.ImportWireMockOrg.cs
Normal file
@@ -0,0 +1,306 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
using OrgMapping = WireMock.Org.Abstractions.Mapping;
|
||||
|
||||
namespace WireMock.Server
|
||||
{
|
||||
public partial class WireMockServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Read WireMock.org mapping json file.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to the WireMock.org mapping json file.</param>
|
||||
[PublicAPI]
|
||||
public void ReadStaticWireMockOrgMappingAndAddOrUpdate([NotNull] string path)
|
||||
{
|
||||
Check.NotNull(path, nameof(path));
|
||||
|
||||
string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
|
||||
|
||||
if (FileHelper.TryReadMappingFileWithRetryAndDelay(_settings.FileSystemHandler, path, out string value))
|
||||
{
|
||||
var mappings = DeserializeJsonToArray<OrgMapping>(value);
|
||||
foreach (var mapping in mappings)
|
||||
{
|
||||
if (mappings.Length == 1 && Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
|
||||
{
|
||||
ConvertWireMockOrgMappingAndRegisterAsRespondProvider(mapping, guidFromFilename, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConvertWireMockOrgMappingAndRegisterAsRespondProvider(mapping, null, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ResponseMessage MappingsPostWireMockOrg(RequestMessage requestMessage)
|
||||
{
|
||||
try
|
||||
{
|
||||
var mappingModels = DeserializeRequestMessageToArray<OrgMapping>(requestMessage);
|
||||
if (mappingModels.Length == 1)
|
||||
{
|
||||
Guid? guid = ConvertWireMockOrgMappingAndRegisterAsRespondProvider(mappingModels[0]);
|
||||
return ResponseMessageBuilder.Create("Mapping added", 201, guid);
|
||||
}
|
||||
|
||||
foreach (var mappingModel in mappingModels)
|
||||
{
|
||||
ConvertWireMockOrgMappingAndRegisterAsRespondProvider(mappingModel);
|
||||
}
|
||||
|
||||
return ResponseMessageBuilder.Create("Mappings added", 201);
|
||||
}
|
||||
catch (ArgumentException a)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to 400 {0}", a);
|
||||
return ResponseMessageBuilder.Create(a.Message, 400);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_settings.Logger.Error("HttpStatusCode set to 500 {0}", e);
|
||||
return ResponseMessageBuilder.Create(e.ToString(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
private Guid? ConvertWireMockOrgMappingAndRegisterAsRespondProvider(OrgMapping mapping, Guid? guid = null, string path = null)
|
||||
{
|
||||
var requestBuilder = Request.Create();
|
||||
|
||||
var request = mapping.Request;
|
||||
if (request != null)
|
||||
{
|
||||
if (request.Url != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithUrl(request.Url);
|
||||
}
|
||||
else if (request.UrlPattern != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithUrl(new RegexMatcher(request.UrlPattern));
|
||||
}
|
||||
else if (request.UrlPath != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithPath(request.Url);
|
||||
}
|
||||
else if (request.UrlPathPattern != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.WithPath(new RegexMatcher(request.UrlPathPattern));
|
||||
}
|
||||
|
||||
if (request.Method != null)
|
||||
{
|
||||
requestBuilder = requestBuilder.UsingMethod(request.Method);
|
||||
}
|
||||
|
||||
/*
|
||||
"headers" : {
|
||||
"Accept" : {
|
||||
"contains" : "xml"
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (request.Headers is JObject headers)
|
||||
{
|
||||
ProcessWireMockOrgJObjectAndUseStringMatcher(headers, (key, match) =>
|
||||
{
|
||||
requestBuilder = requestBuilder.WithHeader(key, match as IStringMatcher);
|
||||
});
|
||||
}
|
||||
|
||||
if (request.Cookies is JObject cookies)
|
||||
{
|
||||
ProcessWireMockOrgJObjectAndUseStringMatcher(cookies, (key, match) =>
|
||||
{
|
||||
requestBuilder = requestBuilder.WithCookie(key, match as IStringMatcher);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
"queryParameters" : {
|
||||
"search_term" : {
|
||||
"equalTo" : "WireMock"
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (request.QueryParameters is JObject queryParameters)
|
||||
{
|
||||
ProcessWireMockOrgJObjectAndUseStringMatcher(queryParameters, (key, match) =>
|
||||
{
|
||||
requestBuilder = requestBuilder.WithParam(key, match);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
"bodyPatterns" : [ {
|
||||
"equalToJson" : "{ "cityName": "São Paulo", "cityCode": 5001 },
|
||||
"ignoreArrayOrder" : true,
|
||||
"ignoreExtraElements" : true
|
||||
} ]
|
||||
*/
|
||||
if (request.BodyPatterns?.Any() == true)
|
||||
{
|
||||
var jObjectArray = request.BodyPatterns.Cast<JObject>();
|
||||
var bodyPattern = jObjectArray.First();
|
||||
ProcessWireMockOrgJObjectAndUseIMatcher(bodyPattern, (match) =>
|
||||
{
|
||||
requestBuilder = requestBuilder.WithBody(match);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
IResponseBuilder responseBuilder = Response.Create();
|
||||
|
||||
var response = mapping.Response;
|
||||
if (response != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithStatusCode(response.Status);
|
||||
|
||||
if (response.Headers is JObject responseHeaders)
|
||||
{
|
||||
ProcessWireMockOrgJObjectAndConvertToIDictionary(responseHeaders, (headers) =>
|
||||
{
|
||||
responseBuilder = responseBuilder.WithHeaders(headers);
|
||||
});
|
||||
}
|
||||
|
||||
if (response.Transformers != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithTransformer();
|
||||
}
|
||||
|
||||
if (response.Body != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBody(response.Body);
|
||||
}
|
||||
|
||||
if (response.JsonBody != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBodyAsJson(response.JsonBody);
|
||||
}
|
||||
|
||||
if (response.Base64Body != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBody(Encoding.UTF8.GetString(Convert.FromBase64String(response.Base64Body)));
|
||||
}
|
||||
|
||||
if (response.BodyFileName != null)
|
||||
{
|
||||
responseBuilder = responseBuilder.WithBodyFromFile(response.BodyFileName);
|
||||
}
|
||||
}
|
||||
|
||||
var respondProvider = Given(requestBuilder);
|
||||
if (guid != null)
|
||||
{
|
||||
respondProvider = respondProvider.WithGuid(guid.Value);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(mapping.Uuid))
|
||||
{
|
||||
respondProvider = respondProvider.WithGuid(new Guid(mapping.Uuid));
|
||||
}
|
||||
|
||||
if (mapping.Name != null)
|
||||
{
|
||||
respondProvider = respondProvider.WithTitle(mapping.Name);
|
||||
}
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
respondProvider = respondProvider.WithPath(path);
|
||||
}
|
||||
|
||||
respondProvider.RespondWith(responseBuilder);
|
||||
|
||||
return respondProvider.Guid;
|
||||
}
|
||||
|
||||
private void ProcessWireMockOrgJObjectAndConvertToIDictionary(JObject items, Action<IDictionary<string, string>> action)
|
||||
{
|
||||
var dict = new Dictionary<string, string>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
var key = item.Key;
|
||||
var valueAsString = item.Value.Value<string>();
|
||||
dict.Add(key, valueAsString);
|
||||
}
|
||||
|
||||
action(dict);
|
||||
}
|
||||
|
||||
private void ProcessWireMockOrgJObjectAndUseStringMatcher(JObject items, Action<string, IStringMatcher> action)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
var key = item.Key;
|
||||
var match = item.Value.First as JProperty;
|
||||
var valueAsString = match?.Value.Value<string>();
|
||||
if (string.IsNullOrEmpty(valueAsString))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var matcher = ProcessAsStringMatcher(match, valueAsString);
|
||||
if (matcher != null)
|
||||
{
|
||||
action(key, matcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessWireMockOrgJObjectAndUseIMatcher(JObject items, Action<IMatcher> action)
|
||||
{
|
||||
IMatcher matcher = null;
|
||||
|
||||
var firstItem = items.First as JProperty;
|
||||
|
||||
if (firstItem?.Name == "equalToJson")
|
||||
{
|
||||
matcher = new JsonMatcher(firstItem.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
var valueAsString = (firstItem.Value as JValue)?.Value as string;
|
||||
if (valueAsString == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
matcher = ProcessAsStringMatcher(firstItem, valueAsString);
|
||||
}
|
||||
|
||||
if (matcher != null)
|
||||
{
|
||||
action(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
private static IStringMatcher ProcessAsStringMatcher(JProperty match, string valueAsString)
|
||||
{
|
||||
switch (match?.Name)
|
||||
{
|
||||
case "contains":
|
||||
return new WildcardMatcher(valueAsString);
|
||||
|
||||
case "matches":
|
||||
return new RegexMatcher(valueAsString);
|
||||
|
||||
case "equalTo":
|
||||
return new ExactMatcher(valueAsString);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,5 +132,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\WireMock.Org.Abstractions\WireMock.Org.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
12
src/WireMock.Org.Abstractions/BasicAuthCredentials.cs
Normal file
12
src/WireMock.Org.Abstractions/BasicAuthCredentials.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
/// Pre-emptive basic auth credentials to match against
|
||||
/// </summary>
|
||||
public class BasicAuthCredentials
|
||||
{
|
||||
public string Password { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class GetAdminMappingsResponse
|
||||
{
|
||||
public Mapping[] Mappings { get; set; }
|
||||
|
||||
public Meta Meta { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class GetAdminRecordingsStatusResponse
|
||||
{
|
||||
public string Status { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class GetAdminRequestsUnmatchedNearMissesResponse
|
||||
{
|
||||
public NearMiss[] NearMisses { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class GetAdminScenariosResponse
|
||||
{
|
||||
public Scenario[] Scenarios { get; set; }
|
||||
}
|
||||
}
|
||||
59
src/WireMock.Org.Abstractions/Mapping.cs
Normal file
59
src/WireMock.Org.Abstractions/Mapping.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class Mapping
|
||||
{
|
||||
/// <summary>
|
||||
/// This stub mapping's unique identifier
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the id
|
||||
/// </summary>
|
||||
public string Uuid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The stub mapping's name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
public Request Request { get; set; }
|
||||
|
||||
public Response Response { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the stub mapping should be persisted immediately on create/update/delete and survive resets to default.
|
||||
/// </summary>
|
||||
public bool Persistent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This stub mapping's priority relative to others. 1 is highest.
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the scenario that this stub mapping is part of
|
||||
/// </summary>
|
||||
public string ScenarioName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The required state of the scenario in order for this stub to be matched.
|
||||
/// </summary>
|
||||
public string RequiredScenarioState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The new state for the scenario to be updated to after this stub is served.
|
||||
/// </summary>
|
||||
public string NewScenarioState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A map of the names of post serve action extensions to trigger and their parameters.
|
||||
/// </summary>
|
||||
public object PostServeActions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Arbitrary metadata to be used for e.g. tagging, documentation. Can also be used to find and remove stubs.
|
||||
/// </summary>
|
||||
public object Metadata { get; set; }
|
||||
}
|
||||
}
|
||||
7
src/WireMock.Org.Abstractions/Meta.cs
Normal file
7
src/WireMock.Org.Abstractions/Meta.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class Meta
|
||||
{
|
||||
public int Total { get; set; }
|
||||
}
|
||||
}
|
||||
35
src/WireMock.Org.Abstractions/NearMiss.cs
Normal file
35
src/WireMock.Org.Abstractions/NearMiss.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class NearMiss
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP request method
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path and query to match exactly against
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The full URL to match against
|
||||
/// </summary>
|
||||
public string AbsoluteUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header patterns to match against in the <key>: { "<predicate>": "<value>" } form
|
||||
/// </summary>
|
||||
public object Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cookie patterns to match against in the <key>: { "<predicate>": "<value>" } form
|
||||
/// </summary>
|
||||
public object Cookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Body string to match against
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class PostAdminRequestsCountResponse
|
||||
{
|
||||
public int Count { get; set; }
|
||||
}
|
||||
}
|
||||
55
src/WireMock.Org.Abstractions/Request.cs
Normal file
55
src/WireMock.Org.Abstractions/Request.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP request method e.g. GET
|
||||
/// </summary>
|
||||
public string Method { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path and query to match exactly against. Only one of url, urlPattern, urlPath or urlPathPattern may be specified.
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to match exactly against. Only one of url, urlPattern, urlPath or urlPathPattern may be specified.
|
||||
/// </summary>
|
||||
public string UrlPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path regex to match against. Only one of url, urlPattern, urlPath or urlPathPattern may be specified.
|
||||
/// </summary>
|
||||
public string UrlPathPattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path and query regex to match against. Only one of url, urlPattern, urlPath or urlPathPattern may be specified.
|
||||
/// </summary>
|
||||
public string UrlPattern { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Query parameter patterns to match against in the <key>: { "<predicate>": "<value>" } form
|
||||
/// </summary>
|
||||
public object QueryParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Header patterns to match against in the <key>: { "<predicate>": "<value>" } form
|
||||
/// </summary>
|
||||
public object Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Pre-emptive basic auth credentials to match against
|
||||
/// </summary>
|
||||
public BasicAuthCredentials BasicAuthCredentials { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cookie patterns to match against in the <key>: { "<predicate>": "<value>" } form
|
||||
/// </summary>
|
||||
public object Cookies { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Request body patterns to match against in the <key>: { "<predicate>": "<value>" } form
|
||||
/// </summary>
|
||||
public object[] BodyPatterns { get; set; }
|
||||
}
|
||||
}
|
||||
75
src/WireMock.Org.Abstractions/Response.cs
Normal file
75
src/WireMock.Org.Abstractions/Response.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class Response
|
||||
{
|
||||
/// <summary>
|
||||
/// The HTTP status code to be returned
|
||||
/// </summary>
|
||||
public int Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The HTTP status message to be returned
|
||||
/// </summary>
|
||||
public string StatusMessage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Map of response headers to send
|
||||
/// </summary>
|
||||
public object Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Extra request headers to send when proxying to another host.
|
||||
/// </summary>
|
||||
public object AdditionalProxyRequestHeaders { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The response body as a string. Only one of body, base64Body, jsonBody or bodyFileName may be specified.
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The response body as a base64 encoded string (useful for binary content). Only one of body, base64Body, jsonBody or bodyFileName may be specified.
|
||||
/// </summary>
|
||||
public string Base64Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The response body as a JSON object. Only one of body, base64Body, jsonBody or bodyFileName may be specified.
|
||||
/// </summary>
|
||||
public object JsonBody { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to the file containing the response body, relative to the configured file root. Only one of body, base64Body, jsonBody or bodyFileName may be specified.
|
||||
/// </summary>
|
||||
public string BodyFileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The fault to apply (instead of a full, valid response).
|
||||
/// </summary>
|
||||
public string Fault { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Number of milliseconds to delay be before sending the response.
|
||||
/// </summary>
|
||||
public int FixedDelayMilliseconds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Read-only flag indicating false if this was the default, unmatched response. Not present otherwise.
|
||||
/// </summary>
|
||||
public bool FromConfiguredStub { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The base URL of the target to proxy matching requests to.
|
||||
/// </summary>
|
||||
public string ProxyBaseUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parameters to apply to response transformers.
|
||||
/// </summary>
|
||||
public object TransformerParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// List of names of transformers to apply to this response.
|
||||
/// </summary>
|
||||
public string Transformers { get; set; }
|
||||
}
|
||||
}
|
||||
14
src/WireMock.Org.Abstractions/ResponseLogNormal.cs
Normal file
14
src/WireMock.Org.Abstractions/ResponseLogNormal.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
/// Log normal randomly distributed response delay.
|
||||
/// </summary>
|
||||
public class ResponseLogNormal
|
||||
{
|
||||
public int Median { get; set; }
|
||||
|
||||
public double Sigma { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
/// Uniformly distributed random response delay.
|
||||
/// </summary>
|
||||
public class ResponseLogUniformlyDistributed
|
||||
{
|
||||
public int Lower { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
|
||||
public int Upper { get; set; }
|
||||
}
|
||||
}
|
||||
22
src/WireMock.Org.Abstractions/Scenario.cs
Normal file
22
src/WireMock.Org.Abstractions/Scenario.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace WireMock.Org.Abstractions
|
||||
{
|
||||
public class Scenario
|
||||
{
|
||||
/// <summary>
|
||||
/// The scenario ID
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The scenario name
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
public string PossibleStates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The current state of this scenario
|
||||
/// </summary>
|
||||
public string State { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>Commonly used interfaces, models, enumerations and types.</Description>
|
||||
<AssemblyTitle>WireMock.Org.Abstractions</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net45;netstandard1.0;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);1591;8603</NoWarn>
|
||||
|
||||
<AssemblyName>WireMock.Org.Abstractions</AssemblyName>
|
||||
<PackageId>WireMock.Org.Abstractions</PackageId>
|
||||
<PackageTags>wiremock;wiremock.org;interfaces;models;classes;enumerations;types</PackageTags>
|
||||
<RootNamespace>WireMock</RootNamespace>
|
||||
<ProjectGuid>{3BA5109E-5F30-4CC2-B699-02EC82560AA6}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
<!--<DelaySign>true</DelaySign>-->
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!--<PackageReference Include="AnyOf" Version="0.0.23" />-->
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
6332
src/WireMock.Org.Abstractions/wiremock.org.json
Normal file
6332
src/WireMock.Org.Abstractions/wiremock.org.json
Normal file
File diff suppressed because it is too large
Load Diff
232
src/WireMock.Org.RestClient/IWireMockOrgApi.cs
Normal file
232
src/WireMock.Org.RestClient/IWireMockOrgApi.cs
Normal file
@@ -0,0 +1,232 @@
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using RestEase;
|
||||
using WireMock.Org.Abstractions;
|
||||
|
||||
namespace WireMock.Org.RestClient
|
||||
{
|
||||
/// <summary>
|
||||
/// WireMockOrg
|
||||
/// </summary>
|
||||
public interface IWireMockOrgApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all stub mappings
|
||||
/// </summary>
|
||||
/// <param name="limit">The maximum number of results to return</param>
|
||||
/// <param name="offset">The start index of the results to return</param>
|
||||
[Get("/__admin/mappings")]
|
||||
Task<GetAdminMappingsResponse> GetAdminMappingsAsync([Query] int? limit, [Query] int? offset);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new stub mapping
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/mappings")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<Mapping> PostAdminMappingsAsync([Body] Mapping request);
|
||||
|
||||
/// <summary>
|
||||
/// Delete all stub mappings
|
||||
/// </summary>
|
||||
[Delete("/__admin/mappings")]
|
||||
Task DeleteAdminMappingsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Reset stub mappings
|
||||
/// </summary>
|
||||
[Post("/__admin/mappings/reset")]
|
||||
Task PostAdminMappingsResetAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Persist stub mappings
|
||||
/// </summary>
|
||||
[Post("/__admin/mappings/save")]
|
||||
Task PostAdminMappingsSaveAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Get stub mapping by ID
|
||||
/// </summary>
|
||||
[Get("/__admin/mappings/{stubMappingId}")]
|
||||
Task<Mapping> GetAdminMappingsByStubMappingIdAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Update a stub mapping
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Put("/__admin/mappings/{stubMappingId}")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<Mapping> PutAdminMappingsByStubMappingIdAsync([Body] Mapping request);
|
||||
|
||||
/// <summary>
|
||||
/// Delete a stub mapping
|
||||
/// </summary>
|
||||
[Delete("/__admin/mappings/{stubMappingId}")]
|
||||
Task DeleteAdminMappingsByStubMappingIdAsync();
|
||||
|
||||
/// <summary>
|
||||
/// PostAdminMappingsFindByMetadata (/__admin/mappings/find-by-metadata)
|
||||
/// </summary>
|
||||
[Post("/__admin/mappings/find-by-metadata")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<GetAdminMappingsResponse> PostAdminMappingsFindByMetadataAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Delete stub mappings matching metadata
|
||||
/// </summary>
|
||||
[Post("/__admin/mappings/remove-by-metadata")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task PostAdminMappingsRemoveByMetadataAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Get all requests in journal
|
||||
/// </summary>
|
||||
/// <param name="limit">The maximum number of results to return</param>
|
||||
/// <param name="since">Only return logged requests after this date</param>
|
||||
[Get("/__admin/requests")]
|
||||
Task GetAdminRequestsAsync([Query] string limit, [Query] string since);
|
||||
|
||||
/// <summary>
|
||||
/// Delete all requests in journal
|
||||
/// </summary>
|
||||
[Delete("/__admin/requests")]
|
||||
Task DeleteAdminRequestsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Get request by ID
|
||||
/// </summary>
|
||||
/// <param name="requestId">The UUID of the logged request</param>
|
||||
[Get("/__admin/requests/{requestId}")]
|
||||
Task GetAdminRequestsByRequestIdAsync([Path] string requestId);
|
||||
|
||||
/// <summary>
|
||||
/// Delete request by ID
|
||||
/// </summary>
|
||||
/// <param name="requestId">The UUID of the logged request</param>
|
||||
[Delete("/__admin/requests/{requestId}")]
|
||||
Task DeleteAdminRequestsByRequestIdAsync([Path] string requestId);
|
||||
|
||||
/// <summary>
|
||||
/// Empty the request journal
|
||||
/// </summary>
|
||||
[Post("/__admin/requests/reset")]
|
||||
Task PostAdminRequestsResetAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Count requests by criteria
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/requests/count")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<PostAdminRequestsCountResponse> PostAdminRequestsCountAsync([Body] Request request);
|
||||
|
||||
/// <summary>
|
||||
/// Remove requests by criteria
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/requests/remove")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task PostAdminRequestsRemoveAsync([Body] Request request);
|
||||
|
||||
/// <summary>
|
||||
/// Delete requests mappings matching metadata
|
||||
/// </summary>
|
||||
[Post("/__admin/requests/remove-by-metadata")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task PostAdminRequestsRemoveByMetadataAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Find requests by criteria
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/requests/find")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task PostAdminRequestsFindAsync([Body] Request request);
|
||||
|
||||
/// <summary>
|
||||
/// Find unmatched requests
|
||||
/// </summary>
|
||||
[Get("/__admin/requests/unmatched")]
|
||||
Task GetAdminRequestsUnmatchedAsync();
|
||||
|
||||
/// <summary>
|
||||
/// GetAdminRequestsUnmatchedNearMisses (/__admin/requests/unmatched/near-misses)
|
||||
/// </summary>
|
||||
[Get("/__admin/requests/unmatched/near-misses")]
|
||||
Task<GetAdminRequestsUnmatchedNearMissesResponse> GetAdminRequestsUnmatchedNearMissesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Find near misses matching specific request
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/near-misses/request")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<GetAdminRequestsUnmatchedNearMissesResponse> PostAdminNearMissesRequestAsync([Body] NearMiss request);
|
||||
|
||||
/// <summary>
|
||||
/// Find near misses matching request pattern
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/near-misses/request-pattern")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<GetAdminRequestsUnmatchedNearMissesResponse> PostAdminNearMissesRequestPatternAsync([Body] Request request);
|
||||
|
||||
/// <summary>
|
||||
/// Start recording
|
||||
/// </summary>
|
||||
[Post("/__admin/recordings/start")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task PostAdminRecordingsStartAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Stop recording
|
||||
/// </summary>
|
||||
[Post("/__admin/recordings/stop")]
|
||||
Task<GetAdminMappingsResponse> PostAdminRecordingsStopAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Get recording status
|
||||
/// </summary>
|
||||
[Get("/__admin/recordings/status")]
|
||||
Task<GetAdminRecordingsStatusResponse> GetAdminRecordingsStatusAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Take a snapshot recording
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
[Post("/__admin/recordings/snapshot")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task<GetAdminMappingsResponse> PostAdminRecordingsSnapshotAsync([Body] object request);
|
||||
|
||||
/// <summary>
|
||||
/// Get all scenarios
|
||||
/// </summary>
|
||||
[Get("/__admin/scenarios")]
|
||||
Task<GetAdminScenariosResponse> GetAdminScenariosAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Reset the state of all scenarios
|
||||
/// </summary>
|
||||
[Post("/__admin/scenarios/reset")]
|
||||
Task PostAdminScenariosResetAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Update global settings
|
||||
/// </summary>
|
||||
[Post("/__admin/settings")]
|
||||
[Header("Content-Type", "application/json")]
|
||||
Task PostAdminSettingsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Reset mappings and request journal
|
||||
/// </summary>
|
||||
[Post("/__admin/reset")]
|
||||
Task PostAdminResetAsync();
|
||||
|
||||
/// <summary>
|
||||
/// PostAdminShutdown (/__admin/shutdown)
|
||||
/// </summary>
|
||||
[Post("/__admin/shutdown")]
|
||||
Task PostAdminShutdownAsync();
|
||||
}
|
||||
}
|
||||
41
src/WireMock.Org.RestClient/WireMock.Org.RestClient.csproj
Normal file
41
src/WireMock.Org.RestClient/WireMock.Org.RestClient.csproj
Normal file
@@ -0,0 +1,41 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Description>A WireMock.org RestClient using RestEase to access the admin interface.</Description>
|
||||
<AssemblyTitle>WireMock.Org.RestClient</AssemblyTitle>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net45;netstandard1.1;netstandard2.0;netstandard2.1</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<AssemblyName>WireMock.Org.RestClient</AssemblyName>
|
||||
<PackageId>WireMock.Org.RestClient</PackageId>
|
||||
<PackageTags>wiremock;wiremock.org;rest;client;restclient;restease;rest;json</PackageTags>
|
||||
<RootNamespace>WireMock.Org.Client</RootNamespace>
|
||||
<ProjectGuid>{08B29DB1-FEFE-408A-AD0A-6BA6DDC8D70F}</ProjectGuid>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
<CodeAnalysisRuleSet>../WireMock.Net/WireMock.Net.ruleset</CodeAnalysisRuleSet>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>../WireMock.Net/WireMock.Net.snk</AssemblyOriginatorKeyFile>
|
||||
<!--<DelaySign>true</DelaySign>-->
|
||||
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<!--<PathMap>$(MSBuildProjectDirectory)=/</PathMap>-->
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
<PackageReference Include="RestEase" Version="1.5.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WireMock.Org.Abstractions\WireMock.Org.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
@@ -51,7 +51,7 @@
|
||||
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
||||
<PackageReference Include="Moq" Version="4.16.0" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="RestEase" Version="1.4.10" />
|
||||
<PackageReference Include="RestEase" Version="1.5.5" />
|
||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.12" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
@@ -72,6 +72,9 @@
|
||||
<None Update="responsebody.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings.org\mapping1.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="__admin\mappings\00000002-ee28-4f29-ae63-1ac9b0802d86.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
31
test/WireMock.Net.Tests/WireMockServer.ImportWireMockOrg.cs
Normal file
31
test/WireMock.Net.Tests/WireMockServer.ImportWireMockOrg.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using WireMock.Server;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests
|
||||
{
|
||||
public class WireMockServerImportWireMockOrgTests
|
||||
{
|
||||
// For for AppVeyor + OpenCover
|
||||
private string GetCurrentFolder()
|
||||
{
|
||||
return Directory.GetCurrentDirectory();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WireMockServer_Admin_ReadStaticWireMockOrgMappingAndAddOrUpdate()
|
||||
{
|
||||
var server = WireMockServer.Start();
|
||||
string path = Path.Combine(GetCurrentFolder(), "__admin", "mappings.org", "mapping1.json");
|
||||
server.ReadStaticWireMockOrgMappingAndAddOrUpdate(path);
|
||||
|
||||
var mappings = server.Mappings.ToArray();
|
||||
|
||||
mappings.Should().HaveCount(1);
|
||||
|
||||
server.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace WireMock.Net.Tests
|
||||
|
||||
// Assert
|
||||
var mappings = server.Mappings;
|
||||
Check.That(mappings.Count()).IsEqualTo(24);
|
||||
Check.That(mappings.Count()).IsEqualTo(25);
|
||||
Check.That(mappings.All(m => m.Priority == int.MinValue)).IsTrue();
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ namespace WireMock.Net.Tests
|
||||
|
||||
// Assert
|
||||
var mappings = server.Mappings;
|
||||
Check.That(mappings.Count()).IsEqualTo(25);
|
||||
Check.That(mappings.Count(m => m.Priority == int.MinValue)).IsEqualTo(24);
|
||||
Check.That(mappings.Count()).IsEqualTo(26);
|
||||
Check.That(mappings.Count(m => m.Priority == int.MinValue)).IsEqualTo(25);
|
||||
Check.That(mappings.Count(m => m.Priority == 1000)).IsEqualTo(1);
|
||||
}
|
||||
|
||||
|
||||
38
test/WireMock.Net.Tests/__admin/mappings.org/mapping1.json
Normal file
38
test/WireMock.Net.Tests/__admin/mappings.org/mapping1.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"id": "ef53ea56-f118-4b3a-8c69-a9484851d99a",
|
||||
"name": "weatherforecast",
|
||||
"request": {
|
||||
"path": "/WeatherForecast/register-city",
|
||||
"method": "POST",
|
||||
"headers": {
|
||||
"XXX": {
|
||||
"contains": "xml"
|
||||
}
|
||||
},
|
||||
"queryParameters": {
|
||||
"search_term": {
|
||||
"equalTo": "WireMock"
|
||||
}
|
||||
},
|
||||
"bodyPatterns": [
|
||||
{
|
||||
"equalToJson": {
|
||||
"cityName": "São Paulo",
|
||||
"cityCode": 5001
|
||||
},
|
||||
"ignoreArrayOrder": true,
|
||||
"ignoreExtraElements": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
"body": "[{\"date\":\"2021-09-09T20:44:48.0992639-03:00\",\"temperatureC\":51,\"temperatureF\":123,\"summary\":\"Hot\"},{\"date\":\"2021-09-10T20:44:48.0992692-03:00\",\"temperatureC\":34,\"temperatureF\":93,\"summary\":\"Mild\"},{\"date\":\"2021-09-11T20:44:48.0992696-03:00\",\"temperatureC\":43,\"temperatureF\":109,\"summary\":\"Sweltering\"},{\"date\":\"2021-09-12T20:44:48.0992698-03:00\",\"temperatureC\":46,\"temperatureF\":114,\"summary\":\"Cool\"},{\"date\":\"2021-09-13T20:44:48.0992701-03:00\",\"temperatureC\":3,\"temperatureF\":37,\"summary\":\"Freezing\"}]",
|
||||
"headers": {
|
||||
"Content-Type": "application/json; charset=utf-8"
|
||||
}
|
||||
},
|
||||
"uuid": "ef53ea56-f118-4b3a-8c69-a9484851d99a",
|
||||
"persistent": true,
|
||||
"insertionIndex": 1
|
||||
}
|
||||
Reference in New Issue
Block a user