Update REST Admin interface to support "Get Mapping(s) as C# Code" (#878)

* Add /__admin/mappings/code endpoint

* api

* fix

* .

* fix

* .

* .

* .
This commit is contained in:
Stef Heyenrath
2023-01-29 10:24:58 +01:00
committed by GitHub
parent 0fc664b404
commit 7fe2c8af78
45 changed files with 900 additions and 448 deletions

View File

@@ -106,8 +106,19 @@ namespace WireMock.Net.ConsoleApplication
//server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef"); //server.SetAzureADAuthentication("6c2a4722-f3b9-4970-b8fc-fac41e29stef", "8587fde1-7824-42c7-8592-faf92b04stef");
// server.AllowPartialMapping(); // server.AllowPartialMapping();
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
.WithBody("Hello World")
);
server.Given(Request.Create().WithPath(MatchOperator.Or, "/mypath", "/mypath1", "/mypath2").UsingPost()) server.Given(Request.Create().WithPath(MatchOperator.Or, "/mypath", "/mypath1", "/mypath2").UsingPost())
.WithGuid("86984b0e-2516-4935-a2ef-b45bf4820d7d")
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithHeader("Content-Type", "application/json") .WithHeader("Content-Type", "application/json")
.WithBodyAsJson("{{JsonPath.SelectToken request.body \"..name\"}}") .WithBodyAsJson("{{JsonPath.SelectToken request.body \"..name\"}}")
@@ -380,7 +391,7 @@ namespace WireMock.Net.ConsoleApplication
// http://localhost:9091/trans?start=1000&stop=1&stop=2 // http://localhost:9091/trans?start=1000&stop=1&stop=2
server server
.Given(Request.Create().WithPath("/trans").UsingGet()) .Given(Request.Create().WithPath("/trans").UsingGet())
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05") .WithGuid("90356dba-b36c-469a-a17e-669cd84f1f06")
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithStatusCode(200) .WithStatusCode(200)
.WithHeader("Content-Type", "application/json") .WithHeader("Content-Type", "application/json")

View File

@@ -78,6 +78,11 @@ public interface IRequestMessage
/// </summary> /// </summary>
IDictionary<string, WireMockList<string>>? Query { get; } IDictionary<string, WireMockList<string>>? Query { get; }
/// <summary>
/// Gets the query.
/// </summary>
IDictionary<string, WireMockList<string>>? QueryIgnoreCase { get; }
/// <summary> /// <summary>
/// Gets the raw query. /// Gets the raw query.
/// </summary> /// </summary>

View File

@@ -3,212 +3,227 @@ using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Types;
namespace WireMock.Server namespace WireMock.Server;
/// <summary>
/// The fluent mock server interface.
/// </summary>
public interface IWireMockServer : IDisposable
{ {
/// <summary> /// <summary>
/// The fluent mock server interface. /// Gets a value indicating whether this server is started.
/// </summary> /// </summary>
public interface IWireMockServer : IDisposable bool IsStarted { get; }
{
/// <summary>
/// Gets a value indicating whether this server is started.
/// </summary>
bool IsStarted { get; }
/// <summary> /// <summary>
/// Gets the request logs. /// Gets the request logs.
/// </summary> /// </summary>
IEnumerable<ILogEntry> LogEntries { get; } IEnumerable<ILogEntry> LogEntries { get; }
/// <summary> /// <summary>
/// Gets the mappings as MappingModels. /// Gets the mappings as MappingModels.
/// </summary> /// </summary>
IEnumerable<MappingModel> MappingModels { get; } IEnumerable<MappingModel> MappingModels { get; }
// <summary> // <summary>
// Gets the mappings. // Gets the mappings.
// </summary> // </summary>
//[PublicAPI] //[PublicAPI]
//IEnumerable<IMapping> Mappings { get; } //IEnumerable<IMapping> Mappings { get; }
/// <summary> /// <summary>
/// Gets the ports. /// Gets the ports.
/// </summary> /// </summary>
List<int> Ports { get; } List<int> Ports { get; }
/// <summary> /// <summary>
/// Gets the first port. /// Gets the first port.
/// </summary> /// </summary>
int Port { get; } int Port { get; }
/// <summary> /// <summary>
/// Gets the urls. /// Gets the urls.
/// </summary> /// </summary>
string[] Urls { get; } string[] Urls { get; }
/// <summary> /// <summary>
/// Gets the first url. /// Gets the first url.
/// </summary> /// </summary>
string? Url { get; } string? Url { get; }
/// <summary> /// <summary>
/// Gets the consumer. /// Gets the consumer.
/// </summary> /// </summary>
string? Consumer { get; } string? Consumer { get; }
/// <summary> /// <summary>
/// Gets the provider. /// Gets the provider.
/// </summary> /// </summary>
string? Provider { get; } string? Provider { get; }
//ConcurrentDictionary<string, ScenarioState> Scenarios { get; } //ConcurrentDictionary<string, ScenarioState> Scenarios { get; }
/// <summary> /// <summary>
/// Occurs when [log entries changed]. /// Occurs when [log entries changed].
/// </summary> /// </summary>
event NotifyCollectionChangedEventHandler LogEntriesChanged; event NotifyCollectionChangedEventHandler LogEntriesChanged;
/// <summary> /// <summary>
/// Adds a 'catch all mapping' /// Adds a 'catch all mapping'
/// ///
/// - matches all Paths and any Methods /// - matches all Paths and any Methods
/// - priority is set to 1000 /// - priority is set to 1000
/// - responds with a 404 "No matching mapping found" /// - responds with a 404 "No matching mapping found"
/// </summary> /// </summary>
void AddCatchAllMapping(); void AddCatchAllMapping();
/// <summary> /// <summary>
/// The add request processing delay. /// The add request processing delay.
/// </summary> /// </summary>
/// <param name="delay">The delay.</param> /// <param name="delay">The delay.</param>
void AddGlobalProcessingDelay(TimeSpan delay); void AddGlobalProcessingDelay(TimeSpan delay);
/// <summary> /// <summary>
/// Allows the partial mapping. /// Allows the partial mapping.
/// </summary> /// </summary>
void AllowPartialMapping(bool allow = true); void AllowPartialMapping(bool allow = true);
/// <summary> /// <summary>
/// Deletes a LogEntry. /// Deletes a LogEntry.
/// </summary> /// </summary>
/// <param name="guid">The unique identifier.</param> /// <param name="guid">The unique identifier.</param>
bool DeleteLogEntry(Guid guid); bool DeleteLogEntry(Guid guid);
/// <summary> /// <summary>
/// Deletes the mapping. /// Deletes the mapping.
/// </summary> /// </summary>
/// <param name="guid">The unique identifier.</param> /// <param name="guid">The unique identifier.</param>
bool DeleteMapping(Guid guid); bool DeleteMapping(Guid guid);
//IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers); //IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers);
// IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false); // IRespondWithAProvider Given(IRequestMatcher requestMatcher, bool saveToFile = false);
/// <summary> /// <summary>
/// Reads a static mapping file and adds or updates a single mapping. /// Reads a static mapping file and adds or updates a single mapping.
/// ///
/// Calling this method manually forces WireMock.Net to read and apply the specified static mapping file. /// Calling this method manually forces WireMock.Net to read and apply the specified static mapping file.
/// </summary> /// </summary>
/// <param name="path">The path to the static mapping file.</param> /// <param name="path">The path to the static mapping file.</param>
bool ReadStaticMappingAndAddOrUpdate(string path); bool ReadStaticMappingAndAddOrUpdate(string path);
/// <summary> /// <summary>
/// Reads the static mappings from a folder. /// Reads the static mappings from a folder.
/// (This method is also used when WireMockServerSettings.ReadStaticMappings is set to true. /// (This method is also used when WireMockServerSettings.ReadStaticMappings is set to true.
/// ///
/// Calling this method manually forces WireMock.Net to read and apply all static mapping files in the specified folder. /// Calling this method manually forces WireMock.Net to read and apply all static mapping files in the specified folder.
/// </summary> /// </summary>
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param> /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
void ReadStaticMappings(string? folder = null); void ReadStaticMappings(string? folder = null);
/// <summary> /// <summary>
/// Removes the authentication. /// Removes the authentication.
/// </summary> /// </summary>
void RemoveAuthentication(); void RemoveAuthentication();
/// <summary> /// <summary>
/// Resets LogEntries and Mappings. /// Resets LogEntries and Mappings.
/// </summary> /// </summary>
void Reset(); void Reset();
/// <summary> /// <summary>
/// Resets the Mappings. /// Resets the Mappings.
/// </summary> /// </summary>
void ResetMappings(); void ResetMappings();
/// <summary> /// <summary>
/// Resets all Scenarios. /// Resets all Scenarios.
/// </summary> /// </summary>
void ResetScenarios(); void ResetScenarios();
/// <summary> /// <summary>
/// Resets a specific Scenario by the name. /// Resets a specific Scenario by the name.
/// </summary> /// </summary>
bool ResetScenario(string name); bool ResetScenario(string name);
/// <summary> /// <summary>
/// Resets the LogEntries. /// Resets the LogEntries.
/// </summary> /// </summary>
void ResetLogEntries(); void ResetLogEntries();
/// <summary> /// <summary>
/// Saves the static mappings. /// Saves the static mappings.
/// </summary> /// </summary>
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param> /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
void SaveStaticMappings(string? folder = null); void SaveStaticMappings(string? folder = null);
/// <summary> /// <summary>
/// Sets the basic authentication. /// Sets the basic authentication.
/// </summary> /// </summary>
/// <param name="tenant">The Tenant.</param> /// <param name="tenant">The Tenant.</param>
/// <param name="audience">The Audience or Resource.</param> /// <param name="audience">The Audience or Resource.</param>
void SetAzureADAuthentication(string tenant, string audience); void SetAzureADAuthentication(string tenant, string audience);
/// <summary> /// <summary>
/// Sets the basic authentication. /// Sets the basic authentication.
/// </summary> /// </summary>
/// <param name="username">The username.</param> /// <param name="username">The username.</param>
/// <param name="password">The password.</param> /// <param name="password">The password.</param>
void SetBasicAuthentication(string username, string password); void SetBasicAuthentication(string username, string password);
/// <summary> /// <summary>
/// Sets the maximum RequestLog count. /// Sets the maximum RequestLog count.
/// </summary> /// </summary>
/// <param name="maxRequestLogCount">The maximum RequestLog count.</param> /// <param name="maxRequestLogCount">The maximum RequestLog count.</param>
void SetMaxRequestLogCount(int? maxRequestLogCount); void SetMaxRequestLogCount(int? maxRequestLogCount);
/// <summary> /// <summary>
/// Sets RequestLog expiration in hours. /// Sets RequestLog expiration in hours.
/// </summary> /// </summary>
/// <param name="requestLogExpirationDuration">The RequestLog expiration in hours.</param> /// <param name="requestLogExpirationDuration">The RequestLog expiration in hours.</param>
void SetRequestLogExpirationDuration(int? requestLogExpirationDuration); void SetRequestLogExpirationDuration(int? requestLogExpirationDuration);
/// <summary> /// <summary>
/// Stop this server. /// Stop this server.
/// </summary> /// </summary>
void Stop(); void Stop();
/// <summary> /// <summary>
/// Watches the static mappings for changes. /// Watches the static mappings for changes.
/// </summary> /// </summary>
/// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param> /// <param name="folder">The optional folder. If not defined, use {CurrentFolder}/__admin/mappings</param>
void WatchStaticMappings(string? folder = null); void WatchStaticMappings(string? folder = null);
/// <summary> /// <summary>
/// Register the mappings (via <see cref="MappingModel"/>). /// Register the mappings (via <see cref="MappingModel"/>).
/// ///
/// This can be used if you have 1 or more <see cref="MappingModel"/> defined and want to register these in WireMock.Net directly instead of using the fluent syntax. /// This can be used if you have 1 or more <see cref="MappingModel"/> defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
/// </summary> /// </summary>
/// <param name="mappings">The MappingModels</param> /// <param name="mappings">The MappingModels</param>
IWireMockServer WithMapping(params MappingModel[] mappings); IWireMockServer WithMapping(params MappingModel[] mappings);
/// <summary> /// <summary>
/// Register the mappings (via json string). /// Register the mappings (via json string).
/// ///
/// This can be used if you the mappings as json string defined and want to register these in WireMock.Net directly instead of using the fluent syntax. /// This can be used if you the mappings as json string defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
/// </summary> /// </summary>
/// <param name="mappings">The mapping(s) as json string.</param> /// <param name="mappings">The mapping(s) as json string.</param>
IWireMockServer WithMapping(string mappings); IWireMockServer WithMapping(string mappings);
}
/// <summary>
/// Get the C# code for a mapping.
/// </summary>
/// <param name="guid">The Mapping Guid.</param>
/// <param name="converterType">The <see cref="MappingConverterType"/></param>
/// <returns>C# code (null in case the mapping is not found)</returns>
string? MappingToCSharpCode(Guid guid, MappingConverterType converterType);
/// <summary>
/// Get the C# code for all mappings.
/// </summary>
/// <param name="converterType">The <see cref="MappingConverterType"/></param>
/// <returns>C# code</returns>
public string MappingsToCSharpCode(MappingConverterType converterType);
} }

View File

@@ -7,6 +7,7 @@ using WireMock.Admin.Mappings;
using WireMock.Admin.Requests; using WireMock.Admin.Requests;
using WireMock.Admin.Scenarios; using WireMock.Admin.Scenarios;
using WireMock.Admin.Settings; using WireMock.Admin.Settings;
using WireMock.Types;
namespace WireMock.Client namespace WireMock.Client
{ {
@@ -52,6 +53,13 @@ namespace WireMock.Client
[Get("mappings")] [Get("mappings")]
Task<IList<MappingModel>> GetMappingsAsync(); Task<IList<MappingModel>> GetMappingsAsync();
/// <summary>
/// Get the C# code from all mappings
/// </summary>
/// <returns>C# code</returns>
[Get("mappings/code")]
Task<string> GetMappingsCodeAsync([Query] MappingConverterType mappingConverterType = MappingConverterType.Server);
/// <summary> /// <summary>
/// Add a new mapping. /// Add a new mapping.
/// </summary> /// </summary>
@@ -97,6 +105,15 @@ namespace WireMock.Client
[Get("mappings/{guid}")] [Get("mappings/{guid}")]
Task<MappingModel> GetMappingAsync([Path] Guid guid); Task<MappingModel> GetMappingAsync([Path] Guid guid);
/// <summary>
/// Get the C# code from a mapping based on the guid
/// </summary>
/// <param name="guid">The Guid</param>
/// <param name="mappingConverterType">The optional mappingConverterType (can be Server or Builder)</param>
/// <returns>C# code</returns>
[Get("mappings/code/{guid}")]
Task<string> GetMappingCodeAsync([Path] Guid guid, [Query] MappingConverterType mappingConverterType = MappingConverterType.Server);
/// <summary> /// <summary>
/// Update a mapping based on the guid /// Update a mapping based on the guid
/// </summary> /// </summary>

View File

@@ -7,4 +7,5 @@ internal static class WireMockConstants
public const int ProxyPriority = -2_000_000; public const int ProxyPriority = -2_000_000;
public const string ContentTypeJson = "application/json"; public const string ContentTypeJson = "application/json";
public const string ContentTypeTextPlain = "text/plain";
} }

View File

@@ -1,6 +1,8 @@
using System;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Matchers.Request; using WireMock.Matchers.Request;
using WireMock.Server; using WireMock.Server;
using WireMock.Types;
namespace WireMock; namespace WireMock;
@@ -40,4 +42,19 @@ public interface IMappingBuilder
/// </summary> /// </summary>
/// <param name="folder">The folder to write the files to.</param> /// <param name="folder">The folder to write the files to.</param>
void SaveMappingsToFolder(string folder); void SaveMappingsToFolder(string folder);
/// <summary>
/// Get the C# code for a mapping.
/// </summary>
/// <param name="guid">The Mapping Guid.</param>
/// <param name="converterType">The <see cref="MappingConverterType"/></param>
/// <returns>C# code (null in case the mapping is not found)</returns>
string? ToCSharpCode(Guid guid, MappingConverterType converterType);
/// <summary>
/// Get the C# code for all mappings.
/// </summary>
/// <param name="converterType">The <see cref="MappingConverterType"/></param>
/// <returns>C# code</returns>
public string ToCSharpCode(MappingConverterType converterType);
} }

View File

@@ -1,4 +1,6 @@
using System;
using System.Linq; using System.Linq;
using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
using Stef.Validation; using Stef.Validation;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
@@ -7,6 +9,7 @@ using WireMock.Owin;
using WireMock.Serialization; using WireMock.Serialization;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
using WireMock.Types;
using WireMock.Util; using WireMock.Util;
namespace WireMock; namespace WireMock;
@@ -66,10 +69,12 @@ public class MappingBuilder : IMappingBuilder
/// <inheritdoc /> /// <inheritdoc />
public MappingModel[] GetMappings() public MappingModel[] GetMappings()
{ {
return _options.Mappings.Values.ToArray() return GetMappingsInternal().Select(_mappingConverter.ToMappingModel).ToArray();
.Where(m => !m.IsAdminInterface) }
.Select(_mappingConverter.ToMappingModel)
.ToArray(); internal IMapping[] GetMappingsInternal()
{
return _options.Mappings.Values.ToArray().Where(m => !m.IsAdminInterface).ToArray();
} }
/// <inheritdoc /> /// <inheritdoc />
@@ -78,6 +83,37 @@ public class MappingBuilder : IMappingBuilder
return ToJson(GetMappings()); return ToJson(GetMappings());
} }
/// <inheritdoc />
public string? ToCSharpCode(Guid guid, MappingConverterType converterType)
{
var mapping = GetMappingsInternal().FirstOrDefault(m => m.Guid == guid);
if (mapping is null)
{
return null;
}
var settings = new MappingConverterSettings { AddStart = true, ConverterType = converterType };
return _mappingConverter.ToCSharpCode(mapping, settings);
}
/// <inheritdoc />
public string ToCSharpCode(MappingConverterType converterType)
{
var sb = new StringBuilder();
bool addStart = true;
foreach (var mapping in GetMappingsInternal())
{
sb.AppendLine(_mappingConverter.ToCSharpCode(mapping, new MappingConverterSettings { AddStart = addStart, ConverterType = converterType }));
if (addStart)
{
addStart = false;
}
}
return sb.ToString();
}
/// <inheritdoc /> /// <inheritdoc />
public void SaveMappingsToFile(string path) public void SaveMappingsToFile(string path)
{ {

View File

@@ -56,9 +56,12 @@ public class RequestMessage : IRequestMessage
/// <inheritdoc cref="IRequestMessage.Cookies" /> /// <inheritdoc cref="IRequestMessage.Cookies" />
public IDictionary<string, string>? Cookies { get; } public IDictionary<string, string>? Cookies { get; }
/// <inheritdoc cref="IRequestMessage.Query" /> /// <inheritdoc />
public IDictionary<string, WireMockList<string>>? Query { get; } public IDictionary<string, WireMockList<string>>? Query { get; }
/// <inheritdoc />
public IDictionary<string, WireMockList<string>>? QueryIgnoreCase { get; }
/// <inheritdoc cref="IRequestMessage.RawQuery" /> /// <inheritdoc cref="IRequestMessage.RawQuery" />
public string RawQuery { get; } public string RawQuery { get; }
@@ -171,6 +174,7 @@ public class RequestMessage : IRequestMessage
Cookies = cookies; Cookies = cookies;
RawQuery = urlDetails.Url.Query; RawQuery = urlDetails.Url.Query;
Query = QueryStringParser.Parse(RawQuery, options?.QueryParameterMultipleValueSupport); Query = QueryStringParser.Parse(RawQuery, options?.QueryParameterMultipleValueSupport);
QueryIgnoreCase = new Dictionary<string, WireMockList<string>>(Query, StringComparer.OrdinalIgnoreCase);
#if USE_ASPNETCORE #if USE_ASPNETCORE
ClientCertificate = clientCertificate; ClientCertificate = clientCertificate;
#endif #endif

View File

@@ -33,7 +33,7 @@ internal class MappingConverter
settings ??= new MappingConverterSettings(); settings ??= new MappingConverterSettings();
var request = (Request)mapping.RequestMatcher; var request = (Request)mapping.RequestMatcher;
var response = (Response)mapping.Provider; var response = (Response) mapping.Provider;
var clientIPMatcher = request.GetRequestMessageMatcher<RequestMessageClientIPMatcher>(); var clientIPMatcher = request.GetRequestMessageMatcher<RequestMessageClientIPMatcher>();
var pathMatcher = request.GetRequestMessageMatcher<RequestMessagePathMatcher>(); var pathMatcher = request.GetRequestMessageMatcher<RequestMessagePathMatcher>();

View File

@@ -31,7 +31,7 @@ internal class RespondWithAProvider : IRespondWithAProvider
private readonly IDateTimeUtils _dateTimeUtils; private readonly IDateTimeUtils _dateTimeUtils;
private readonly bool _saveToFile; private readonly bool _saveToFile;
private bool _useWebhookFireAndForget; private bool? _useWebhookFireAndForget;
public Guid Guid { get; private set; } public Guid Guid { get; private set; }

View File

@@ -32,6 +32,7 @@ public partial class WireMockServer
private const int EnhancedFileSystemWatcherTimeoutMs = 1000; private const int EnhancedFileSystemWatcherTimeoutMs = 1000;
private const string AdminFiles = "/__admin/files"; private const string AdminFiles = "/__admin/files";
private const string AdminMappings = "/__admin/mappings"; private const string AdminMappings = "/__admin/mappings";
private const string AdminMappingsCode = "/__admin/mappings/code";
private const string AdminMappingsWireMockOrg = "/__admin/mappings/wiremock.org"; private const string AdminMappingsWireMockOrg = "/__admin/mappings/wiremock.org";
private const string AdminRequests = "/__admin/requests"; private const string AdminRequests = "/__admin/requests";
private const string AdminSettings = "/__admin/settings"; private const string AdminSettings = "/__admin/settings";
@@ -41,6 +42,7 @@ public partial class WireMockServer
private static readonly Guid ProxyMappingGuid = new("e59914fd-782e-428e-91c1-4810ffb86567"); private static readonly Guid ProxyMappingGuid = new("e59914fd-782e-428e-91c1-4810ffb86567");
private static readonly RegexMatcher AdminRequestContentTypeJson = new ContentTypeMatcher(WireMockConstants.ContentTypeJson, true); private static readonly RegexMatcher AdminRequestContentTypeJson = new ContentTypeMatcher(WireMockConstants.ContentTypeJson, true);
private static readonly RegexMatcher AdminMappingsGuidPathMatcher = new(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$"); private static readonly RegexMatcher AdminMappingsGuidPathMatcher = new(@"^\/__admin\/mappings\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private static readonly RegexMatcher AdminMappingsCodeGuidPathMatcher = new(@"^\/__admin\/mappings\/code\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private static readonly RegexMatcher AdminRequestsGuidPathMatcher = new(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$"); private static readonly RegexMatcher AdminRequestsGuidPathMatcher = new(@"^\/__admin\/requests\/([0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12})$");
private static readonly RegexMatcher AdminScenariosNameMatcher = new(@"^\/__admin\/scenarios\/.+$"); private static readonly RegexMatcher AdminScenariosNameMatcher = new(@"^\/__admin\/scenarios\/.+$");
private static readonly RegexMatcher AdminScenariosNameWithResetMatcher = new(@"^\/__admin\/scenarios\/.+\/reset$"); private static readonly RegexMatcher AdminScenariosNameWithResetMatcher = new(@"^\/__admin\/scenarios\/.+\/reset$");
@@ -57,9 +59,14 @@ public partial class WireMockServer
// __admin/mappings // __admin/mappings
Given(Request.Create().WithPath(AdminMappings).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsGet)); Given(Request.Create().WithPath(AdminMappings).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsGet));
Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPost)); Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPost));
Given(Request.Create().WithPath(AdminMappingsWireMockOrg).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPostWireMockOrg));
Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete)); Given(Request.Create().WithPath(AdminMappings).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsDelete));
// __admin/mappings/code
Given(Request.Create().WithPath(AdminMappingsCode).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsCodeGet));
// __admin/mappings/wiremock.org
Given(Request.Create().WithPath(AdminMappingsWireMockOrg).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsPostWireMockOrg));
// __admin/mappings/reset // __admin/mappings/reset
Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsReset)); Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsReset));
@@ -68,6 +75,9 @@ public partial class WireMockServer
Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingPut)); Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.ContentType, AdminRequestContentTypeJson)).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingPut));
Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingDelete)); Given(Request.Create().WithPath(AdminMappingsGuidPathMatcher).UsingDelete()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingDelete));
// __admin/mappings/code/{guid}
Given(Request.Create().WithPath(AdminMappingsCodeGuidPathMatcher).UsingGet()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingCodeGet));
// __admin/mappings/save // __admin/mappings/save
Given(Request.Create().WithPath($"{AdminMappings}/save").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsSave)); Given(Request.Create().WithPath($"{AdminMappings}/save").UsingPost()).AtPriority(WireMockConstants.AdminPriority).RespondWith(new DynamicResponseProvider(MappingsSave));
@@ -286,13 +296,11 @@ public partial class WireMockServer
#region Mapping/{guid} #region Mapping/{guid}
private IResponseMessage MappingGet(IRequestMessage requestMessage) private IResponseMessage MappingGet(IRequestMessage requestMessage)
{ {
Guid guid = ParseGuidFromRequestMessage(requestMessage); var mapping = FindMappingByGuid(requestMessage);
var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
if (mapping == null) if (mapping == null)
{ {
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found"); _settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
return ResponseMessageBuilder.Create("Mapping not found", 404); return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
} }
var model = _mappingConverter.ToMappingModel(mapping); var model = _mappingConverter.ToMappingModel(mapping);
@@ -300,31 +308,71 @@ public partial class WireMockServer
return ToJson(model); return ToJson(model);
} }
private IResponseMessage MappingCodeGet(IRequestMessage requestMessage)
{
if (TryParseGuidFromRequestMessage(requestMessage, out var guid))
{
var code = _mappingBuilder.ToCSharpCode(guid, GetMappingConverterType(requestMessage));
if (code is null)
{
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
}
return ToResponseMessage(code);
}
_settings.Logger.Warn("HttpStatusCode set to 400");
return ResponseMessageBuilder.Create("GUID is missing", HttpStatusCode.BadRequest);
}
private static MappingConverterType GetMappingConverterType(IRequestMessage requestMessage)
{
var mappingConverterType = MappingConverterType.Server;
if (requestMessage.QueryIgnoreCase?.TryGetValue(nameof(MappingConverterType), out var values) == true &&
Enum.TryParse(values.FirstOrDefault(), true, out MappingConverterType parsed))
{
mappingConverterType = parsed;
}
return mappingConverterType;
}
private IMapping? FindMappingByGuid(IRequestMessage requestMessage)
{
return TryParseGuidFromRequestMessage(requestMessage, out var guid) ? Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid) : null;
}
private IResponseMessage MappingPut(IRequestMessage requestMessage) private IResponseMessage MappingPut(IRequestMessage requestMessage)
{ {
Guid guid = ParseGuidFromRequestMessage(requestMessage); if (TryParseGuidFromRequestMessage(requestMessage, out var guid))
{
var mappingModel = DeserializeObject<MappingModel>(requestMessage);
var guidFromPut = ConvertMappingAndRegisterAsRespondProvider(mappingModel, guid);
var mappingModel = DeserializeObject<MappingModel>(requestMessage); return ResponseMessageBuilder.Create("Mapping added or updated", HttpStatusCode.OK, guidFromPut);
Guid? guidFromPut = ConvertMappingAndRegisterAsRespondProvider(mappingModel, guid); }
return ResponseMessageBuilder.Create("Mapping added or updated", HttpStatusCode.OK, guidFromPut); _settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
} }
private IResponseMessage MappingDelete(IRequestMessage requestMessage) private IResponseMessage MappingDelete(IRequestMessage requestMessage)
{ {
Guid guid = ParseGuidFromRequestMessage(requestMessage); if (TryParseGuidFromRequestMessage(requestMessage, out var guid) && DeleteMapping(guid))
if (DeleteMapping(guid))
{ {
return ResponseMessageBuilder.Create("Mapping removed", HttpStatusCode.OK, guid); return ResponseMessageBuilder.Create("Mapping removed", HttpStatusCode.OK, guid);
} }
_settings.Logger.Warn("HttpStatusCode set to 404 : Mapping not found");
return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound); return ResponseMessageBuilder.Create("Mapping not found", HttpStatusCode.NotFound);
} }
private static Guid ParseGuidFromRequestMessage(IRequestMessage requestMessage) private static bool TryParseGuidFromRequestMessage(IRequestMessage requestMessage, out Guid guid)
{ {
return Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1)); var lastPart = requestMessage.Path.Split('/').LastOrDefault();
return Guid.TryParse(lastPart, out guid);
} }
#endregion Mapping/{guid} #endregion Mapping/{guid}
@@ -360,6 +408,15 @@ public partial class WireMockServer
return ToJson(ToMappingModels()); return ToJson(ToMappingModels());
} }
private IResponseMessage MappingsCodeGet(IRequestMessage requestMessage)
{
var converterType = GetMappingConverterType(requestMessage);
var code = _mappingBuilder.ToCSharpCode(converterType);
return ToResponseMessage(code);
}
private IResponseMessage MappingsPost(IRequestMessage requestMessage) private IResponseMessage MappingsPost(IRequestMessage requestMessage)
{ {
try try
@@ -464,30 +521,29 @@ public partial class WireMockServer
#region Request/{guid} #region Request/{guid}
private IResponseMessage RequestGet(IRequestMessage requestMessage) private IResponseMessage RequestGet(IRequestMessage requestMessage)
{ {
Guid guid = ParseGuidFromRequestMessage(requestMessage); if (TryParseGuidFromRequestMessage(requestMessage, out var guid))
var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
if (entry == null)
{ {
_settings.Logger.Warn("HttpStatusCode set to 404 : Request not found"); var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid);
return ResponseMessageBuilder.Create("Request not found", 404); if (entry is { })
{
var model = new LogEntryMapper(_options).Map(entry);
return ToJson(model);
}
} }
var model = new LogEntryMapper(_options).Map(entry); _settings.Logger.Warn("HttpStatusCode set to 404 : Request not found");
return ResponseMessageBuilder.Create("Request not found", HttpStatusCode.NotFound);
return ToJson(model);
} }
private IResponseMessage RequestDelete(IRequestMessage requestMessage) private IResponseMessage RequestDelete(IRequestMessage requestMessage)
{ {
Guid guid = ParseGuidFromRequestMessage(requestMessage); if (TryParseGuidFromRequestMessage(requestMessage, out var guid) && DeleteLogEntry(guid))
if (DeleteLogEntry(guid))
{ {
return ResponseMessageBuilder.Create("Request removed"); return ResponseMessageBuilder.Create("Request removed");
} }
return ResponseMessageBuilder.Create("Request not found", 404); _settings.Logger.Warn("HttpStatusCode set to 404 : Request not found");
return ResponseMessageBuilder.Create("Request not found", HttpStatusCode.NotFound);
} }
#endregion Request/{guid} #endregion Request/{guid}
@@ -564,7 +620,7 @@ public partial class WireMockServer
return ResetScenario(name) ? return ResetScenario(name) ?
ResponseMessageBuilder.Create("Scenario reset") : ResponseMessageBuilder.Create("Scenario reset") :
ResponseMessageBuilder.Create($"No scenario found by name '{name}'.", 404); ResponseMessageBuilder.Create($"No scenario found by name '{name}'.", HttpStatusCode.NotFound);
} }
#endregion #endregion
@@ -687,6 +743,20 @@ public partial class WireMockServer
}; };
} }
private static ResponseMessage ToResponseMessage(string text)
{
return new ResponseMessage
{
BodyData = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = text
},
StatusCode = (int)HttpStatusCode.OK,
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>(WireMockConstants.ContentTypeTextPlain) } }
};
}
private static T DeserializeObject<T>(IRequestMessage requestMessage) where T : new() private static T DeserializeObject<T>(IRequestMessage requestMessage) where T : new()
{ {
return requestMessage.BodyData?.DetectedBodyType switch return requestMessage.BodyData?.DetectedBodyType switch

View File

@@ -540,6 +540,20 @@ public partial class WireMockServer : IWireMockServer
return _mappingBuilder.Given(requestMatcher, saveToFile); return _mappingBuilder.Given(requestMatcher, saveToFile);
} }
/// <inheritdoc />
[PublicAPI]
public string? MappingToCSharpCode(Guid guid, MappingConverterType converterType)
{
return _mappingBuilder.ToCSharpCode(guid, converterType);
}
/// <inheritdoc />
[PublicAPI]
public string MappingsToCSharpCode(MappingConverterType converterType)
{
return _mappingBuilder.ToCSharpCode(converterType);
}
private void InitSettings(WireMockServerSettings settings) private void InitSettings(WireMockServerSettings settings)
{ {
if (settings.AllowBodyForAllHttpMethods == true) if (settings.AllowBodyForAllHttpMethods == true)

View File

@@ -1,6 +1,6 @@
[ [
{ {
Guid: 41372914-1838-4c67-916b-b9aacdd096ce, Guid: Guid_1,
UpdatedAt: 2023-01-14 15:16:17, UpdatedAt: 2023-01-14 15:16:17,
Request: { Request: {
Path: { Path: {
@@ -19,7 +19,6 @@
Response: { Response: {
BodyDestination: SameAsSource, BodyDestination: SameAsSource,
Body: { msg: "Hello world!"} Body: { msg: "Hello world!"}
}, }
UseWebhooksFireAndForget: false
} }
] ]

View File

@@ -1,6 +1,6 @@
[ [
{ {
Guid: 41372914-1838-4c67-916b-b9aacdd096ce, Guid: Guid_1,
UpdatedAt: 2023-01-14T15:16:17, UpdatedAt: 2023-01-14T15:16:17,
Request: { Request: {
Path: { Path: {
@@ -19,7 +19,6 @@
Response: { Response: {
BodyDestination: SameAsSource, BodyDestination: SameAsSource,
Body: { msg: "Hello world!"} Body: { msg: "Hello world!"}
}, }
UseWebhooksFireAndForget: false
} }
] ]

View File

@@ -1,12 +1,12 @@
#if !(NET452 || NET461 || NETCOREAPP3_1) #if !(NET452 || NET461 || NETCOREAPP3_1)
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Moq; using Moq;
using VerifyTests; using VerifyTests;
using VerifyXunit; using VerifyXunit;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Net.Tests.VerifyExtensions;
using WireMock.Owin; using WireMock.Owin;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
using WireMock.ResponseBuilders; using WireMock.ResponseBuilders;
@@ -20,6 +20,12 @@ namespace WireMock.Net.Tests;
[UsesVerify] [UsesVerify]
public class MappingBuilderTests public class MappingBuilderTests
{ {
private static readonly VerifySettings VerifySettings = new();
static MappingBuilderTests()
{
VerifySettings.Init();
}
private static readonly Guid NewGuid = new("98fae52e-76df-47d9-876f-2ee32e931d9b"); private static readonly Guid NewGuid = new("98fae52e-76df-47d9-876f-2ee32e931d9b");
private const string MappingGuid = "41372914-1838-4c67-916b-b9aacdd096ce"; private const string MappingGuid = "41372914-1838-4c67-916b-b9aacdd096ce";
private static readonly DateTime UtcNow = new(2023, 1, 14, 15, 16, 17); private static readonly DateTime UtcNow = new(2023, 1, 14, 15, 16, 17);
@@ -67,13 +73,6 @@ public class MappingBuilderTests
); );
} }
[ModuleInitializer]
public static void ModuleInitializer()
{
VerifierSettings.DontScrubGuids();
VerifierSettings.DontScrubDateTimes();
}
[Fact] [Fact]
public Task GetMappings() public Task GetMappings()
{ {
@@ -81,7 +80,7 @@ public class MappingBuilderTests
var mappings = _sut.GetMappings(); var mappings = _sut.GetMappings();
// Verify // Verify
return Verifier.Verify(mappings); return Verifier.Verify(mappings, VerifySettings);
} }
[Fact] [Fact]
@@ -91,7 +90,7 @@ public class MappingBuilderTests
var json = _sut.ToJson(); var json = _sut.ToJson();
// Verify // Verify
return Verifier.VerifyJson(json); return Verifier.VerifyJson(json, VerifySettings);
} }
[Fact] [Fact]

View File

@@ -20,7 +20,7 @@ public class LogEntryMapperTests
private static readonly VerifySettings VerifySettings = new(); private static readonly VerifySettings VerifySettings = new();
static LogEntryMapperTests() static LogEntryMapperTests()
{ {
VerifySettings.Init<LogEntryMapperTests>(); VerifySettings.Init();
} }
private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions(); private readonly IWireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();

View File

@@ -1,10 +1,10 @@
#if !(NET452 || NET461 || NETCOREAPP3_1) #if !(NET452 || NET461 || NETCOREAPP3_1)
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using VerifyTests; using VerifyTests;
using VerifyXunit; using VerifyXunit;
using WireMock.Net.Tests.VerifyExtensions;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
using WireMock.ResponseBuilders; using WireMock.ResponseBuilders;
using WireMock.Serialization; using WireMock.Serialization;
@@ -16,12 +16,10 @@ namespace WireMock.Net.Tests.Serialization;
[UsesVerify] [UsesVerify]
public partial class MappingConverterTests public partial class MappingConverterTests
{ {
private static readonly VerifySettings VerifySettings = new();
[ModuleInitializer] static MappingConverterTests()
public static void ModuleInitializer()
{ {
VerifierSettings.DontScrubGuids(); VerifySettings.Init();
VerifierSettings.DontScrubDateTimes();
} }
[Fact] [Fact]
@@ -41,7 +39,7 @@ public partial class MappingConverterTests
code.Should().NotBeEmpty(); code.Should().NotBeEmpty();
// Verify // Verify
return Verifier.Verify(code); return Verifier.Verify(code, VerifySettings);
} }
[Fact] [Fact]
@@ -61,7 +59,7 @@ public partial class MappingConverterTests
code.Should().NotBeEmpty(); code.Should().NotBeEmpty();
// Verify // Verify
return Verifier.Verify(code); return Verifier.Verify(code, VerifySettings);
} }
[Fact] [Fact]
@@ -81,7 +79,7 @@ public partial class MappingConverterTests
code.Should().NotBeEmpty(); code.Should().NotBeEmpty();
// Verify // Verify
return Verifier.Verify(code); return Verifier.Verify(code, VerifySettings);
} }
[Fact] [Fact]
@@ -101,7 +99,7 @@ public partial class MappingConverterTests
code.Should().NotBeEmpty(); code.Should().NotBeEmpty();
// Verify // Verify
return Verifier.Verify(code); return Verifier.Verify(code, VerifySettings);
} }
private Mapping CreateMapping() private Mapping CreateMapping()

View File

@@ -1,12 +1 @@
{
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9,
UpdatedAt: 2022-12-04 11:12:13,
Title: ,
Description: ,
Priority: 42,
Request: {},
Response: {
Delay: 1000
},
UseWebhooksFireAndForget: false
}

View File

@@ -0,0 +1,12 @@
{
Guid: Guid_1,
UpdatedAt: DateTime_1,
Title: ,
Description: ,
Priority: 42,
Request: {},
Response: {
Delay: 1000
},
UseWebhooksFireAndForget: false
}

View File

@@ -1,6 +1,6 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: DateTime_1,
Title: , Title: ,
Description: , Description: ,
Priority: 42, Priority: 42,

View File

@@ -1,6 +1,6 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: DateTime_1,
Title: , Title: ,
Description: , Description: ,
Priority: 42, Priority: 42,

View File

@@ -1,6 +1,6 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: DateTime_1,
Title: , Title: ,
Description: , Description: ,
Priority: 42, Priority: 42,

View File

@@ -1,5 +1,5 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: 2022-12-04 11:12:13,
TimeSettings: { TimeSettings: {
Start: 2023-01-14 15:16:17, Start: 2023-01-14 15:16:17,

View File

@@ -1,6 +1,6 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: DateTime_1,
Title: my-title, Title: my-title,
Description: my-description, Description: my-description,
Request: {}, Request: {},

View File

@@ -1,6 +1,6 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: DateTime_1,
Title: , Title: ,
Description: , Description: ,
Request: {}, Request: {},

View File

@@ -1,6 +1,6 @@
{ {
Guid: c8eeaf99-d5c4-4341-8543-4597c3fd40d9, Guid: Guid_1,
UpdatedAt: 2022-12-04 11:12:13, UpdatedAt: DateTime_1,
Title: , Title: ,
Description: , Description: ,
Request: {}, Request: {},

View File

@@ -1,11 +1,9 @@
#if !(NET452 || NET461 || NETCOREAPP3_1) #if !(NET452 || NET461 || NETCOREAPP3_1)
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using FluentAssertions; using FluentAssertions;
using VerifyTests;
using VerifyXunit; using VerifyXunit;
using WireMock.Models; using WireMock.Models;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
@@ -232,7 +230,7 @@ public partial class MappingConverterTests
model.TimeSettings.TTL.Should().Be(ttl); model.TimeSettings.TTL.Should().Be(ttl);
// Verify // Verify
return Verifier.Verify(model); return Verifier.Verify(model, VerifySettings);
} }
[Fact] [Fact]
@@ -262,7 +260,7 @@ public partial class MappingConverterTests
} }
[Fact] [Fact]
public Task ToMappingModel_WithDelayAsMilleSeconds_ReturnsCorrectModel() public Task ToMappingModel_WithDelayAsMilliSeconds_ReturnsCorrectModel()
{ {
// Assign // Assign
var delay = 1000; var delay = 1000;

View File

@@ -1,5 +1,5 @@
{ {
Guid: ff55ac0a-fea9-4d7b-be74-5e483a2c1305, Guid: Guid_1,
UpdatedAt: 2022-12-04, UpdatedAt: 2022-12-04,
Title: my title, Title: my title,
Description: my description, Description: my description,

View File

@@ -1,11 +1,11 @@
#if !(NET452 || NET461 || NETCOREAPP3_1) #if !(NET452 || NET461 || NETCOREAPP3_1)
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Moq; using Moq;
using VerifyTests; using VerifyTests;
using VerifyXunit; using VerifyXunit;
using WireMock.Matchers; using WireMock.Matchers;
using WireMock.Net.Tests.VerifyExtensions;
using WireMock.RequestBuilders; using WireMock.RequestBuilders;
using WireMock.Serialization; using WireMock.Serialization;
using WireMock.Settings; using WireMock.Settings;
@@ -17,6 +17,12 @@ namespace WireMock.Net.Tests.Serialization;
[UsesVerify] [UsesVerify]
public class ProxyMappingConverterTests public class ProxyMappingConverterTests
{ {
private static readonly VerifySettings VerifySettings = new();
static ProxyMappingConverterTests()
{
VerifySettings.Init();
}
private readonly WireMockServerSettings _settings = new(); private readonly WireMockServerSettings _settings = new();
private readonly MappingConverter _mappingConverter; private readonly MappingConverter _mappingConverter;
@@ -36,13 +42,6 @@ public class ProxyMappingConverterTests
_sut = new ProxyMappingConverter(_settings, guidUtilsMock.Object, dateTimeUtilsMock.Object); _sut = new ProxyMappingConverter(_settings, guidUtilsMock.Object, dateTimeUtilsMock.Object);
} }
[ModuleInitializer]
public static void ModuleInitializer()
{
VerifierSettings.DontScrubGuids();
VerifierSettings.DontScrubDateTimes();
}
[Fact] [Fact]
public Task ToMapping_UseDefinedRequestMatchers_True() public Task ToMapping_UseDefinedRequestMatchers_True()
{ {
@@ -77,7 +76,7 @@ public class ProxyMappingConverterTests
var model = _mappingConverter.ToMappingModel(proxyMapping); var model = _mappingConverter.ToMappingModel(proxyMapping);
// Verify // Verify
return Verifier.Verify(model); return Verifier.Verify(model, VerifySettings);
} }
} }
#endif #endif

View File

@@ -1,11 +1,11 @@
#if !(NET452 || NET461 || NETCOREAPP3_1) #if !(NET452 || NET461 || NETCOREAPP3_1)
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using VerifyTests; using VerifyTests;
using VerifyXunit; using VerifyXunit;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Models; using WireMock.Models;
using WireMock.Net.Tests.VerifyExtensions;
using WireMock.Serialization; using WireMock.Serialization;
using WireMock.Types; using WireMock.Types;
using WireMock.Util; using WireMock.Util;
@@ -16,11 +16,10 @@ namespace WireMock.Net.Tests.Serialization;
[UsesVerify] [UsesVerify]
public class WebhookMapperTests public class WebhookMapperTests
{ {
[ModuleInitializer] private static readonly VerifySettings VerifySettings = new();
public static void ModuleInitializer() static WebhookMapperTests()
{ {
VerifierSettings.DontScrubGuids(); VerifySettings.Init();
VerifierSettings.DontScrubDateTimes();
} }
[Fact] [Fact]
@@ -45,7 +44,7 @@ public class WebhookMapperTests
var result = WebhookMapper.Map(model); var result = WebhookMapper.Map(model);
// Verify // Verify
return Verifier.Verify(result); return Verifier.Verify(result, VerifySettings);
} }
[Fact] [Fact]
@@ -70,7 +69,7 @@ public class WebhookMapperTests
var result = WebhookMapper.Map(model); var result = WebhookMapper.Map(model);
// Verify // Verify
return Verifier.Verify(result); return Verifier.Verify(result, VerifySettings);
} }
[Fact] [Fact]
@@ -97,7 +96,7 @@ public class WebhookMapperTests
var result = WebhookMapper.Map(model); var result = WebhookMapper.Map(model);
// Verify // Verify
return Verifier.Verify(result); return Verifier.Verify(result, VerifySettings);
} }
[Fact] [Fact]
@@ -129,7 +128,7 @@ public class WebhookMapperTests
var result = WebhookMapper.Map(webhook); var result = WebhookMapper.Map(webhook);
// Verify // Verify
return Verifier.Verify(result); return Verifier.Verify(result, VerifySettings);
} }
} }
#endif #endif

View File

@@ -0,0 +1,42 @@
#if !(NET452 || NET461)
using System.Collections.Generic;
using System.Collections.Specialized;
using Newtonsoft.Json.Linq;
using VerifyTests;
namespace WireMock.Net.Tests.VerifyExtensions;
internal static class VerifyNewtonsoftJson
{
public static void Enable(VerifySettings verifySettings)
{
// InnerVerifier.ThrowIfVerifyHasBeenRun();
verifySettings
.AddExtraSettings(_ =>
{
var converters = _.Converters;
converters.Add(new JArrayConverter());
converters.Add(new JObjectConverter());
});
}
}
internal class JArrayConverter : WriteOnlyJsonConverter<JArray>
{
public override void Write(VerifyJsonWriter writer, JArray value)
{
var list = value.ToObject<List<object>>()!;
writer.Serialize(list);
}
}
internal class JObjectConverter : WriteOnlyJsonConverter<JObject>
{
public override void Write(VerifyJsonWriter writer, JObject value)
{
var dictionary = value.ToObject<OrderedDictionary>()!;
writer.Serialize(dictionary);
}
}
#endif

View File

@@ -5,11 +5,13 @@ namespace WireMock.Net.Tests.VerifyExtensions;
internal static class VerifySettingsExtensions internal static class VerifySettingsExtensions
{ {
public static void Init<T>(this VerifySettings verifySettings) public static void Init(this VerifySettings verifySettings)
{ {
verifySettings.DontScrubDateTimes(); verifySettings.DontScrubDateTimes();
verifySettings.DontScrubDateTimes(); verifySettings.DontScrubDateTimes();
verifySettings.UseDirectory($"{typeof(T).Name}.Verify"); // verifySettings.UseDirectory($"{typeof(T).Name}.Verify");
VerifyNewtonsoftJson.Enable(verifySettings);
} }
} }
#endif #endif

View File

@@ -61,7 +61,7 @@
<PackageReference Include="Moq" Version="4.17.2" /> <PackageReference Include="Moq" Version="4.17.2" />
<PackageReference Include="System.Threading" Version="4.3.0" /> <PackageReference Include="System.Threading" Version="4.3.0" />
<PackageReference Include="RestEase" Version="1.5.7" /> <PackageReference Include="RestEase" Version="1.5.7" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="NFluent" Version="2.8.0" /> <PackageReference Include="NFluent" Version="2.8.0" />
<PackageReference Include="SimMetrics.Net" Version="1.0.5" /> <PackageReference Include="SimMetrics.Net" Version="1.0.5" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.23" /> <PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.23" />

View File

@@ -0,0 +1,26 @@
{
Guid: 90356dba-b36c-469a-a17e-669cd84f1f05,
UpdatedAt: DateTime_1,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /1,
IgnoreCase: false
}
]
},
Body: {
Matcher: {
Name: RegexMatcher,
Pattern: hello,
IgnoreCase: true
}
}
},
Response: {
Body: world
},
UseWebhooksFireAndForget: false
}

View File

@@ -0,0 +1,35 @@
{
Guid: 90356dba-b36c-469a-a17e-669cd84f1f05,
UpdatedAt: DateTime_1,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /foo1,
IgnoreCase: false
}
]
},
Methods: [
GET
],
Params: [
{
Name: p1,
Matchers: [
{
Name: ExactMatcher,
Pattern: xyz,
IgnoreCase: false
}
]
}
]
},
Response: {
StatusCode: 200,
BodyDestination: SameAsSource,
Body: 1
}
}

View File

@@ -0,0 +1,11 @@
var server = WireMockServer.Start();
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
.WithBody("1")
);

View File

@@ -0,0 +1,24 @@
var server = WireMockServer.Start();
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo1")
.WithParam("p1", "xyz")
)
.WithGuid("90356dba-b36c-469a-a17e-669cd84f1f05")
.RespondWith(Response.Create()
.WithBody("1")
);
server
.Given(Request.Create()
.UsingMethod("GET")
.WithPath("/foo2")
.WithParam("p2", "abc")
)
.WithGuid("1b731398-4a5b-457f-a6e3-d65e541c428f")
.RespondWith(Response.Create()
.WithHeader("hk)", "hv")
.WithBody("2")
);

View File

@@ -1,4 +1,4 @@
#if !NET452 && !NET461 #if !(NET452 || NET461 || NETCOREAPP3_1)
using System; using System;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
@@ -9,20 +9,32 @@ using FluentAssertions;
using Moq; using Moq;
using NFluent; using NFluent;
using RestEase; using RestEase;
using VerifyTests;
using VerifyXunit;
using WireMock.Admin.Mappings; using WireMock.Admin.Mappings;
using WireMock.Admin.Settings; using WireMock.Admin.Settings;
using WireMock.Client; using WireMock.Client;
using WireMock.Handlers; using WireMock.Handlers;
using WireMock.Logging; using WireMock.Logging;
using WireMock.Models; using WireMock.Models;
using WireMock.Net.Tests.VerifyExtensions;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Server; using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
using Xunit; using Xunit;
namespace WireMock.Net.Tests; namespace WireMock.Net.Tests;
[UsesVerify]
public class WireMockAdminApiTests public class WireMockAdminApiTests
{ {
private static readonly VerifySettings VerifySettings = new();
static WireMockAdminApiTests()
{
VerifyNewtonsoftJson.Enable(VerifySettings);
}
[Fact] [Fact]
public async Task IWireMockAdminApi_GetSettingsAsync() public async Task IWireMockAdminApi_GetSettingsAsync()
{ {
@@ -298,9 +310,9 @@ public class WireMockAdminApiTests
public async Task IWireMockAdminApi_GetMappingAsync_WithBodyModelMatcherModel_WithoutMethods_ShouldReturnCorrectMappingModel() public async Task IWireMockAdminApi_GetMappingAsync_WithBodyModelMatcherModel_WithoutMethods_ShouldReturnCorrectMappingModel()
{ {
// Arrange // Arrange
var guid = Guid.NewGuid(); var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
var server = WireMockServer.StartWithAdminInterface(); var server = WireMockServer.StartWithAdminInterface();
var api = RestClient.For<IWireMockAdminApi>(server.Urls[0]); var api = RestClient.For<IWireMockAdminApi>(server.Url);
// Act // Act
var model = new MappingModel var model = new MappingModel
@@ -330,9 +342,8 @@ public class WireMockAdminApiTests
mapping.Should().NotBeNull(); mapping.Should().NotBeNull();
var getMappingResult = await api.GetMappingAsync(guid).ConfigureAwait(false); var getMappingResult = await api.GetMappingAsync(guid).ConfigureAwait(false);
getMappingResult.Should().NotBeNull();
getMappingResult.Request.Body.Should().BeEquivalentTo(model.Request.Body); await Verifier.Verify(getMappingResult, VerifySettings).DontScrubGuids();
server.Stop(); server.Stop();
} }
@@ -629,5 +640,125 @@ public class WireMockAdminApiTests
var status = await api.ResetScenarioAsync(name).ConfigureAwait(false); var status = await api.ResetScenarioAsync(name).ConfigureAwait(false);
status.Status.Should().Be("No scenario found by name 'x'."); status.Status.Should().Be("No scenario found by name 'x'.");
} }
[Fact]
public async Task IWireMockAdminApi_GetMappingByGuidAsync()
{
// Arrange
var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
var server = WireMockServer.StartWithAdminInterface();
server
.Given(
Request.Create()
.WithPath("/foo1")
.WithParam("p1", "xyz")
.UsingGet()
)
.WithGuid(guid)
.RespondWith(
Response.Create()
.WithStatusCode(200)
.WithBody("1")
);
// Act
var api = RestClient.For<IWireMockAdminApi>(server.Url);
var getMappingResult = await api.GetMappingAsync(guid).ConfigureAwait(false);
// Assert
var mapping = server.Mappings.FirstOrDefault(m => m.Guid == guid);
mapping.Should().NotBeNull();
await Verifier.Verify(getMappingResult, VerifySettings).DontScrubGuids();
server.Stop();
}
[Fact]
public async Task IWireMockAdminApi_GetMappingCodeByGuidAsync()
{
// Arrange
var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
var server = WireMockServer.StartWithAdminInterface();
server
.Given(
Request.Create()
.WithPath("/foo1")
.WithParam("p1", "xyz")
.UsingGet()
)
.WithGuid(guid)
.RespondWith(
Response.Create()
.WithStatusCode(200)
.WithBody("1")
);
// Act
var api = RestClient.For<IWireMockAdminApi>(server.Url);
var mappings = await api.GetMappingsAsync().ConfigureAwait(false);
mappings.Should().HaveCount(1);
var code = await api.GetMappingCodeAsync(guid).ConfigureAwait(false);
// Assert
await Verifier.Verify(code).DontScrubDateTimes().DontScrubGuids();
server.Stop();
}
[Fact]
public async Task IWireMockAdminApi_GetMappingsCode()
{
// Arrange
var guid1 = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
var guid2 = Guid.Parse("1b731398-4a5b-457f-a6e3-d65e541c428f");
var server = WireMockServer.StartWithAdminInterface();
server
.Given(
Request.Create()
.WithPath("/foo1")
.WithParam("p1", "xyz")
.UsingGet()
)
.WithGuid(guid1)
.RespondWith(
Response.Create()
.WithStatusCode(200)
.WithBody("1")
);
server
.Given(
Request.Create()
.WithPath("/foo2")
.WithParam("p2", "abc")
.UsingGet()
)
.WithGuid(guid2)
.RespondWith(
Response.Create()
.WithStatusCode(201)
.WithHeader("hk", "hv")
.WithBody("2")
);
// Act
var api = RestClient.For<IWireMockAdminApi>(server.Url);
var mappings = await api.GetMappingsAsync().ConfigureAwait(false);
mappings.Should().HaveCount(2);
var code = await api.GetMappingsCodeAsync().ConfigureAwait(false);
// Assert
await Verifier.Verify(code).DontScrubDateTimes().DontScrubGuids();
server.Stop();
}
} }
#endif #endif

View File

@@ -117,7 +117,7 @@ public class WireMockServerProxyTests
} }
// Assert // Assert
server.Mappings.Should().HaveCount(30); server.Mappings.Should().HaveCount(32);
} }
[Fact] [Fact]

View File

@@ -10,187 +10,186 @@ using WireMock.Server;
using WireMock.Settings; using WireMock.Settings;
using Xunit; using Xunit;
namespace WireMock.Net.Tests namespace WireMock.Net.Tests;
public class WireMockServerSettingsTests
{ {
public class WireMockServerSettingsTests private readonly Mock<IWireMockLogger> _loggerMock;
public WireMockServerSettingsTests()
{ {
private readonly Mock<IWireMockLogger> _loggerMock; _loggerMock = new Mock<IWireMockLogger>();
_loggerMock.Setup(l => l.Info(It.IsAny<string>(), It.IsAny<object[]>()));
}
public WireMockServerSettingsTests() [Fact]
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceTrue_BasicAuthenticationIsSet()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
_loggerMock = new Mock<IWireMockLogger>(); StartAdminInterface = true,
_loggerMock.Setup(l => l.Info(It.IsAny<string>(), It.IsAny<object[]>())); AdminUsername = "u",
} AdminPassword = "p"
});
[Fact] // Assert
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceTrue_BasicAuthenticationIsSet() var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
options.AuthenticationMatcher.Should().NotBeNull().And.BeOfType<BasicAuthenticationMatcher>();
}
[Fact]
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceTrue_AzureADAuthenticationIsSet()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
// Assign and Act StartAdminInterface = true,
var server = WireMockServer.Start(new WireMockServerSettings AdminAzureADTenant = "t",
AdminAzureADAudience = "a"
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
options.AuthenticationMatcher.Should().NotBeNull().And.BeOfType<AzureADAuthenticationMatcher>();
}
[Fact]
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceFalse_BasicAuthenticationIsNotSet()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
StartAdminInterface = false,
AdminUsername = "u",
AdminPassword = "p"
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthenticationMatcher).IsNull();
}
[Fact]
public void WireMockServer_WireMockServerSettings_PriorityFromAllAdminMappingsIsLow_When_StartAdminInterface_IsTrue()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
StartAdminInterface = true
});
// Assert
server.Mappings.Should().NotBeNull();
server.Mappings.Should().HaveCount(30);
server.Mappings.All(m => m.Priority == WireMockConstants.AdminPriority).Should().BeTrue();
}
[Fact]
public void WireMockServer_WireMockServerSettings_ProxyAndRecordSettings_ProxyPriority_IsMinus2000000_When_StartAdminInterface_IsTrue()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
StartAdminInterface = true,
ProxyAndRecordSettings = new ProxyAndRecordSettings
{ {
StartAdminInterface = true, Url = "www.google.com"
AdminUsername = "u", }
AdminPassword = "p" });
});
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); server.Mappings.Should().NotBeNull();
options.AuthenticationMatcher.Should().NotBeNull().And.BeOfType<BasicAuthenticationMatcher>(); server.Mappings.Should().HaveCount(31);
}
[Fact] server.Mappings.Count(m => m.Priority == WireMockConstants.AdminPriority).Should().Be(30);
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceTrue_AzureADAuthenticationIsSet() server.Mappings.Count(m => m.Priority == WireMockConstants.ProxyPriority).Should().Be(1);
}
[Fact]
public void WireMockServer_WireMockServerSettings_ProxyAndRecordSettings_ProxyPriority_Is0_When_StartAdminInterface_IsFalse()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
// Assign and Act ProxyAndRecordSettings = new ProxyAndRecordSettings
var server = WireMockServer.Start(new WireMockServerSettings
{ {
StartAdminInterface = true, Url = "www.google.com"
AdminAzureADTenant = "t", }
AdminAzureADAudience = "a" });
});
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var mappings = server.Mappings.ToArray();
options.AuthenticationMatcher.Should().NotBeNull().And.BeOfType<AzureADAuthenticationMatcher>(); Check.That(mappings.Count()).IsEqualTo(1);
} Check.That(mappings[0].Priority).IsEqualTo(0);
}
[Fact] [Fact]
public void WireMockServer_WireMockServerSettings_StartAdminInterfaceFalse_BasicAuthenticationIsNotSet() public void WireMockServer_WireMockServerSettings_AllowPartialMapping()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
// Assign and Act Logger = _loggerMock.Object,
var server = WireMockServer.Start(new WireMockServerSettings AllowPartialMapping = true
{ });
StartAdminInterface = false,
AdminUsername = "u",
AdminPassword = "p"
});
// Assert // Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options"); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AuthenticationMatcher).IsNull(); Check.That(options.AllowPartialMapping).Equals(true);
}
[Fact] // Verify
public void WireMockServer_WireMockServerSettings_PriorityFromAllAdminMappingsIsLow_When_StartAdminInterface_IsTrue() _loggerMock.Verify(l => l.Info(It.IsAny<string>(), It.IsAny<bool>()));
}
[Fact]
public void WireMockServer_WireMockServerSettings_AllowBodyForAllHttpMethods()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
// Assign and Act Logger = _loggerMock.Object,
var server = WireMockServer.Start(new WireMockServerSettings AllowBodyForAllHttpMethods = true
{ });
StartAdminInterface = true
});
// Assert // Assert
server.Mappings.Should().NotBeNull(); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
server.Mappings.Should().HaveCount(28); Check.That(options.AllowBodyForAllHttpMethods).Equals(true);
server.Mappings.All(m => m.Priority == WireMockConstants.AdminPriority).Should().BeTrue();
}
[Fact] // Verify
public void WireMockServer_WireMockServerSettings_ProxyAndRecordSettings_ProxyPriority_IsMinus2000000_When_StartAdminInterface_IsTrue() _loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowBodyForAllHttpMethods") && s.Contains("True"))));
}
[Fact]
public void WireMockServer_WireMockServerSettings_AllowOnlyDefinedHttpStatusCodeInResponse()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
// Assign and Act Logger = _loggerMock.Object,
var server = WireMockServer.Start(new WireMockServerSettings AllowOnlyDefinedHttpStatusCodeInResponse = true
{ });
StartAdminInterface = true,
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = "www.google.com"
}
});
// Assert // Assert
server.Mappings.Should().NotBeNull(); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
server.Mappings.Should().HaveCount(29); Check.That(options.AllowOnlyDefinedHttpStatusCodeInResponse).Equals(true);
server.Mappings.Count(m => m.Priority == WireMockConstants.AdminPriority).Should().Be(28); // Verify
server.Mappings.Count(m => m.Priority == WireMockConstants.ProxyPriority).Should().Be(1); _loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowOnlyDefinedHttpStatusCodeInResponse") && s.Contains("True"))));
} }
[Fact] [Fact]
public void WireMockServer_WireMockServerSettings_ProxyAndRecordSettings_ProxyPriority_Is0_When_StartAdminInterface_IsFalse() public void WireMockServer_WireMockServerSettings_RequestLogExpirationDuration()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{ {
// Assign and Act Logger = _loggerMock.Object,
var server = WireMockServer.Start(new WireMockServerSettings RequestLogExpirationDuration = 1
{ });
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = "www.google.com"
}
});
// Assert // Assert
var mappings = server.Mappings.ToArray(); var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(mappings.Count()).IsEqualTo(1); Check.That(options.RequestLogExpirationDuration).IsEqualTo(1);
Check.That(mappings[0].Priority).IsEqualTo(0);
}
[Fact]
public void WireMockServer_WireMockServerSettings_AllowPartialMapping()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = _loggerMock.Object,
AllowPartialMapping = true
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AllowPartialMapping).Equals(true);
// Verify
_loggerMock.Verify(l => l.Info(It.IsAny<string>(), It.IsAny<bool>()));
}
[Fact]
public void WireMockServer_WireMockServerSettings_AllowBodyForAllHttpMethods()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = _loggerMock.Object,
AllowBodyForAllHttpMethods = true
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AllowBodyForAllHttpMethods).Equals(true);
// Verify
_loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowBodyForAllHttpMethods") && s.Contains("True"))));
}
[Fact]
public void WireMockServer_WireMockServerSettings_AllowOnlyDefinedHttpStatusCodeInResponse()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = _loggerMock.Object,
AllowOnlyDefinedHttpStatusCodeInResponse = true
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.AllowOnlyDefinedHttpStatusCodeInResponse).Equals(true);
// Verify
_loggerMock.Verify(l => l.Info(It.Is<string>(s => s.Contains("AllowOnlyDefinedHttpStatusCodeInResponse") && s.Contains("True"))));
}
[Fact]
public void WireMockServer_WireMockServerSettings_RequestLogExpirationDuration()
{
// Assign and Act
var server = WireMockServer.Start(new WireMockServerSettings
{
Logger = _loggerMock.Object,
RequestLogExpirationDuration = 1
});
// Assert
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
Check.That(options.RequestLogExpirationDuration).IsEqualTo(1);
}
} }
} }