mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-11-13 12:23:42 +01:00
Merge branch 'master' into dependabot/nuget/src/WireMock.Net.AspNetCore.Middleware/System.Text.Json-8.0.5
This commit is contained in:
54 files changed
+840
-89
No files matched your search
@@ -1,3 +1,23 @@
|
|||||||
|
# 2.19.0 (07 October 2026)
|
||||||
|
- [#1512](https://github.com/wiremock/WireMock.Net/pull/1512) - Use IDateTimeUtils in WireMockWebSocketContext [bug] contributed by [StefH](https://github.com/StefH)
|
||||||
|
- [#1514](https://github.com/wiremock/WireMock.Net/pull/1514) - Fix DateTime in Response [bug] contributed by [StefH](https://github.com/StefH)
|
||||||
|
- [#1511](https://github.com/wiremock/WireMock.Net/issues/1511) - Incorrect response datetime for mapped response [bug]
|
||||||
|
|
||||||
|
# 2.18.0 (22 September 2026)
|
||||||
|
- [#1510](https://github.com/wiremock/WireMock.Net/pull/1510) - WireMock.Net.OpenApiParser: fix depencency on RamlToOpenApiConverter.SourceOnly [bug] contributed by [StefH](https://github.com/StefH)
|
||||||
|
- [#1508](https://github.com/wiremock/WireMock.Net/issues/1508) - Transitive Dependency Conflict with Microsoft.OpenApi in 2.16.0 [bug]
|
||||||
|
|
||||||
|
# 2.17.0 (21 September 2026)
|
||||||
|
- [#1509](https://github.com/wiremock/WireMock.Net/pull/1509) - Revert to RamlToOpenApiConverter.SourceOnly [bug] contributed by [StefH](https://github.com/StefH)
|
||||||
|
|
||||||
|
# 2.16.0 (19 September 2026)
|
||||||
|
- [#1502](https://github.com/wiremock/WireMock.Net/pull/1502) - Fix #1501: Generate WhenStateIs/WillSetStateTo correctly in ToCSharpCode contributed by [Bafyn](https://github.com/Bafyn)
|
||||||
|
- [#1503](https://github.com/wiremock/WireMock.Net/pull/1503) - Fix FormUrlEncodedMatcher (+ refactor values / matchers logic) contributed by [StefH](https://github.com/StefH)
|
||||||
|
- [#1504](https://github.com/wiremock/WireMock.Net/pull/1504) - Update SharpYaml package to version 2.5.1 [dependencies] contributed by [johnthcall](https://github.com/johnthcall)
|
||||||
|
- [#1505](https://github.com/wiremock/WireMock.Net/pull/1505) - Upgrade dependency RamlToOpenApiConverter to version 0.40.0 [dependencies] contributed by [StefH](https://github.com/StefH)
|
||||||
|
- [#1500](https://github.com/wiremock/WireMock.Net/issues/1500) - Sending a form-urlencoded body with a repeated field name returns HTTP 500 [bug]
|
||||||
|
- [#1501](https://github.com/wiremock/WireMock.Net/issues/1501) - Generated C# code for stateful (Scenario) mappings does not compile and drops the WhenStateIs condition [bug]
|
||||||
|
|
||||||
# 2.15.0 (15 August 2026)
|
# 2.15.0 (15 August 2026)
|
||||||
- [#1495](https://github.com/wiremock/WireMock.Net/pull/1495) - Fix #1494: `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the MatchOperator argument [bug] contributed by [Bafyn](https://github.com/Bafyn)
|
- [#1495](https://github.com/wiremock/WireMock.Net/pull/1495) - Fix #1494: `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the MatchOperator argument [bug] contributed by [Bafyn](https://github.com/Bafyn)
|
||||||
- [#1497](https://github.com/wiremock/WireMock.Net/pull/1497) - Fix WithParam RejectOnMatch inverting the match result #1496 [bug] contributed by [Bafyn](https://github.com/Bafyn)
|
- [#1497](https://github.com/wiremock/WireMock.Net/pull/1497) - Fix WithParam RejectOnMatch inverting the match result #1496 [bug] contributed by [Bafyn](https://github.com/Bafyn)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VersionPrefix>2.15.0</VersionPrefix>
|
<VersionPrefix>2.19.0</VersionPrefix>
|
||||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||||
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/wiremock/WireMock.Net</PackageProjectUrl>
|
||||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0" PrivateAssets="All" />
|
<PackageReference Include="JetBrains.Annotations" Version="2026.2.0" PrivateAssets="All" />
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.400" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.401" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
rem https://github.com/StefH/GitHubReleaseNotes
|
rem https://github.com/StefH/GitHubReleaseNotes
|
||||||
|
|
||||||
SET version=2.15.0
|
SET version=2.19.0
|
||||||
|
|
||||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
|
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels wontfix test question invalid doc duplicate example environment --version %version% --token %GH_TOKEN%
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# 2.15.0 (15 August 2026)
|
# 2.19.0 (07 October 2026)
|
||||||
- #1495 Fix #1494: `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the MatchOperator argument [bug]
|
- #1512 Use IDateTimeUtils in WireMockWebSocketContext [bug]
|
||||||
- #1497 Fix WithParam RejectOnMatch inverting the match result #1496 [bug]
|
- #1514 Fix DateTime in Response [bug]
|
||||||
- #1499 Update Testcontainers [bug]
|
- #1511 Incorrect response datetime for mapped response [bug]
|
||||||
- #1494 `WithClientIP(MatchOperator, params IStringMatcher[])` ignores the `MatchOperator` argument [bug]
|
|
||||||
- #1496 `WithParam(key, MatchBehaviour.RejectOnMatch, values)` inverts the match result [bug]
|
|
||||||
|
|
||||||
The full release notes can be found here: https://github.com/wiremock/WireMock.Net/blob/master/CHANGELOG.md
|
The full release notes can be found here: https://github.com/wiremock/WireMock.Net/blob/master/CHANGELOG.md
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using RestEase;
|
using RestEase;
|
||||||
using WireMock.Admin.Settings;
|
using WireMock.Admin.Settings;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System.IO;
|
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using SharpYaml.Model;
|
using Scriban.Runtime;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Models;
|
using WireMock.Models;
|
||||||
@@ -291,11 +286,21 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
|
|
||||||
var server = WireMockServer.Start(new WireMockServerSettings
|
var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
{
|
{
|
||||||
|
StartAdminInterface = true,
|
||||||
Logger = new WireMockConsoleLogger(),
|
Logger = new WireMockConsoleLogger(),
|
||||||
|
|
||||||
Port = 9091
|
Port = 9091
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server
|
||||||
|
.WhenRequest(r => r
|
||||||
|
.WithPath("/test")
|
||||||
|
.UsingAnyMethod()
|
||||||
|
)
|
||||||
|
.ThenRespondWith(r => r
|
||||||
|
.WithStatusCode(HttpStatusCode.OK)
|
||||||
|
.WithBody("OK")
|
||||||
|
);
|
||||||
|
|
||||||
server
|
server
|
||||||
.WhenRequest(r => r
|
.WhenRequest(r => r
|
||||||
.WithPath("/Content-Length")
|
.WithPath("/Content-Length")
|
||||||
@@ -405,12 +410,26 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
// handlebarsContext.RegisterHelper(transformer.Name, transformer.Render); TODO
|
// handlebarsContext.RegisterHelper(transformer.Name, transformer.Render); TODO
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ScribanRegistrationCallback = (scriptObject, fileSystemHandler) =>
|
||||||
|
{
|
||||||
|
var globals = (ScriptObject)scriptObject;
|
||||||
|
globals.Import("greet", new Func<string, string>(name => $"Hello {name}"));
|
||||||
|
},
|
||||||
|
|
||||||
// Uncomment below if you want to use the CustomFileSystemFileHandler
|
// Uncomment below if you want to use the CustomFileSystemFileHandler
|
||||||
// FileSystemHandler = new CustomFileSystemFileHandler()
|
// FileSystemHandler = new CustomFileSystemFileHandler()
|
||||||
});
|
});
|
||||||
System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
|
System.Console.WriteLine("WireMockServer listening at {0}", string.Join(",", server.Urls));
|
||||||
|
|
||||||
server.SetBasicAuthentication("a", "b");
|
server.SetBasicAuthentication("a", "b");
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath("/scriban/greet").UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBody("{{ greet 'WireMock.Net' }}")
|
||||||
|
.WithTransformer(TransformerType.Scriban)
|
||||||
|
);
|
||||||
|
|
||||||
//server.SetAzureADAuthentication(Environment.GetEnvironmentVariable("WIREMOCK_AAD_TENANT")!, "api://e083d51a-01a6-446c-8ad5-0c5c7f002208");
|
//server.SetAzureADAuthentication(Environment.GetEnvironmentVariable("WIREMOCK_AAD_TENANT")!, "api://e083d51a-01a6-446c-8ad5-0c5c7f002208");
|
||||||
|
|
||||||
//var http = new HttpClient();
|
//var http = new HttpClient();
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Net.StandAlone;
|
using WireMock.Net.StandAlone;
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="WireMock.Net" Version="2.12.0" />
|
<PackageReference Include="WireMock.Net" Version="2.15.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using WireMock.RequestBuilders;
|
using WireMock.RequestBuilders;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
|
|
||||||
|
|||||||
+1
-3
@@ -6,15 +6,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!--<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.7.0" />-->
|
|
||||||
|
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net.OpenApiParser\WireMock.Net.OpenApiParser.csproj" />
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||||
<PackageReference Include="Microsoft.OpenApi" Version="3.7.0" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.OpenApi" Version="3.10.2" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public interface IRequestMessage
|
|||||||
string? ProxyUrl { get; set; }
|
string? ProxyUrl { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the DateTime.
|
/// The DateTime when this request was done.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTime DateTime { get; }
|
DateTime DateTime { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public interface IResponseMessage
|
|||||||
object? StatusCode { get; set; }
|
object? StatusCode { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the DateTime.
|
/// The DateTime when this response was sent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
DateTime DateTime { get; }
|
DateTime DateTime { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
|
namespace WireMock.Extensions;
|
||||||
|
|
||||||
|
internal static class HttpContextExtensions
|
||||||
|
{
|
||||||
|
internal static bool TryGet<T>(this HttpContext httpContext, [NotNullWhen(true)] out T? value)
|
||||||
|
{
|
||||||
|
return httpContext.Items.TryGetValue(nameof(T), out value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ namespace WireMock.Owin.Mappers;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// OwinRequestMapper
|
/// OwinRequestMapper
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class OwinRequestMapper : IOwinRequestMapper
|
internal class OwinRequestMapper(IDateTimeUtils dateTimeUtils) : IOwinRequestMapper
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<RequestMessage> MapAsync(HttpContext context, IWireMockMiddlewareOptions options)
|
public async Task<RequestMessage> MapAsync(HttpContext context, IWireMockMiddlewareOptions options)
|
||||||
@@ -72,7 +72,7 @@ internal class OwinRequestMapper : IOwinRequestMapper
|
|||||||
await request.HttpContext.Connection.GetClientCertificateAsync()
|
await request.HttpContext.Connection.GetClientCertificateAsync()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DateTime = DateTime.UtcNow
|
DateTime = dateTimeUtils.UtcNow
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,12 @@ internal class WireMockMiddleware(
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
// Set the DateTime from the Response to the current DateTime
|
||||||
|
if (response is ResponseMessage responseMessage)
|
||||||
|
{
|
||||||
|
responseMessage.DateTime = dateTimeUtils.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
logger.LogRequestAndResponse(logRequest, request, response, result.Match, result.Partial, activity);
|
logger.LogRequestAndResponse(logRequest, request, response, result.Match, result.Partial, activity);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -73,20 +73,20 @@ internal class WireMockMiddlewareLogger(
|
|||||||
var logEntries = options.LogEntries.ToList();
|
var logEntries = options.LogEntries.ToList();
|
||||||
|
|
||||||
foreach (var logEntry in logEntries
|
foreach (var logEntry in logEntries
|
||||||
.OrderBy(le => le.RequestMessage?.DateTime ?? le.ResponseMessage?.DateTime)
|
.OrderBy(le => le.RequestMessage?.DateTime)
|
||||||
.Take(logEntries.Count - options.MaxRequestLogCount.Value))
|
.Take(logEntries.Count - options.MaxRequestLogCount.Value))
|
||||||
{
|
{
|
||||||
TryRemoveLogEntry(logEntry);
|
TryRemoveLogEntry(logEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the date.
|
// In case RequestLogExpirationDuration has a value greater than 0, try to delete existing request logs based on the RequestMessage date.
|
||||||
if (options.RequestLogExpirationDuration is > 0)
|
if (options.RequestLogExpirationDuration is > 0)
|
||||||
{
|
{
|
||||||
var logEntries = options.LogEntries.ToList();
|
var logEntries = options.LogEntries.ToList();
|
||||||
|
|
||||||
var checkTime = dateTimeUtils.UtcNow.AddHours(-options.RequestLogExpirationDuration.Value);
|
var checkTime = dateTimeUtils.UtcNow.AddHours(-options.RequestLogExpirationDuration.Value);
|
||||||
foreach (var logEntry in logEntries.Where(le => le.RequestMessage?.DateTime < checkTime || le.ResponseMessage?.DateTime < checkTime))
|
foreach (var logEntry in logEntries.Where(le => le.RequestMessage?.DateTime < checkTime))
|
||||||
{
|
{
|
||||||
TryRemoveLogEntry(logEntry);
|
TryRemoveLogEntry(logEntry);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public partial class Response : IResponseBuilder
|
|||||||
{
|
{
|
||||||
var message = responseMessage ?? new ResponseMessage
|
var message = responseMessage ?? new ResponseMessage
|
||||||
{
|
{
|
||||||
DateTime = DateTime.UtcNow // We set it here to the current time.
|
DateTime = DateTime.UtcNow // Initially, this is set to the current time, but will be updated to the real time once the response has been sent.
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Response(message);
|
return new Response(message);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
// This source file is based on mock4net by Alexandre Victoor which is licensed under the Apache 2.0 License.
|
||||||
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
// For more details see 'mock4net/LICENSE.txt' and 'mock4net/readme.md' in this project root.
|
||||||
using System.Linq;
|
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.ResponseBuilders;
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ internal class WebSocketResponseProvider(WebSocketBuilder builder, IGuidUtils gu
|
|||||||
builder,
|
builder,
|
||||||
options,
|
options,
|
||||||
logger,
|
logger,
|
||||||
guidUtils
|
guidUtils,
|
||||||
|
dateTimeUtils
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add to registry
|
// Add to registry
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Scriban.Runtime;
|
||||||
|
using Stef.Validation;
|
||||||
|
using WireMock.Handlers;
|
||||||
|
|
||||||
|
namespace WireMock.Settings;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension methods for <see cref="WireMockServerSettings"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class WireMockServerSettingsExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a strongly typed Scriban registration to <see cref="WireMockServerSettings.ScribanRegistrationCallback"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Members added to the <see cref="ScriptObject"/> are available as globals in Scriban and Scriban-DotLiquid templates.
|
||||||
|
/// When a callback is already configured, it is kept and invoked before <paramref name="registrationCallback"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="settings">The settings.</param>
|
||||||
|
/// <param name="registrationCallback">The action which registers functions, objects or variables on the <see cref="ScriptObject"/>.</param>
|
||||||
|
/// <returns>The same <see cref="WireMockServerSettings"/> instance.</returns>
|
||||||
|
[PublicAPI]
|
||||||
|
public static WireMockServerSettings WithScribanRegistration(this WireMockServerSettings settings, Action<ScriptObject, IFileSystemHandler> registrationCallback)
|
||||||
|
{
|
||||||
|
Guard.NotNull(settings);
|
||||||
|
Guard.NotNull(registrationCallback);
|
||||||
|
|
||||||
|
var existingCallback = settings.ScribanRegistrationCallback;
|
||||||
|
settings.ScribanRegistrationCallback = (scriptObject, fileSystemHandler) =>
|
||||||
|
{
|
||||||
|
existingCallback?.Invoke(scriptObject, fileSystemHandler);
|
||||||
|
registrationCallback((ScriptObject)scriptObject, fileSystemHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using Scriban;
|
using Scriban;
|
||||||
|
using Scriban.Runtime;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
@@ -9,21 +10,40 @@ namespace WireMock.Transformers.Scriban;
|
|||||||
|
|
||||||
internal class ScribanContext : ITransformerContext
|
internal class ScribanContext : ITransformerContext
|
||||||
{
|
{
|
||||||
|
private static readonly MemberRenamerDelegate MemberRenamer = member => member.Name;
|
||||||
|
|
||||||
private readonly TransformerType _transformerType;
|
private readonly TransformerType _transformerType;
|
||||||
|
private readonly ScriptObject? _customGlobals;
|
||||||
|
|
||||||
public IFileSystemHandler FileSystemHandler { get; }
|
public IFileSystemHandler FileSystemHandler { get; }
|
||||||
|
|
||||||
public ScribanContext(IFileSystemHandler fileSystemHandler, TransformerType transformerType)
|
public ScribanContext(IFileSystemHandler fileSystemHandler, TransformerType transformerType, ScriptObject? customGlobals = null)
|
||||||
{
|
{
|
||||||
FileSystemHandler = Guard.NotNull(fileSystemHandler);
|
FileSystemHandler = Guard.NotNull(fileSystemHandler);
|
||||||
_transformerType = transformerType;
|
_transformerType = transformerType;
|
||||||
|
_customGlobals = customGlobals;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ParseAndRender(string text, object model)
|
public string ParseAndRender(string text, object model)
|
||||||
{
|
{
|
||||||
var template = _transformerType == TransformerType.ScribanDotLiquid ? Template.ParseLiquid(text) : Template.Parse(text);
|
var isLiquid = _transformerType == TransformerType.ScribanDotLiquid;
|
||||||
|
var template = isLiquid ? Template.ParseLiquid(text) : Template.Parse(text);
|
||||||
|
|
||||||
return template.Render(model, member => member.Name);
|
if (_customGlobals is null)
|
||||||
|
{
|
||||||
|
return template.Render(model, MemberRenamer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as Template.Render(model, MemberRenamer), but with the custom globals pushed beneath the model so that the model takes precedence.
|
||||||
|
var context = isLiquid ? new LiquidTemplateContext() : new TemplateContext();
|
||||||
|
context.MemberRenamer = MemberRenamer;
|
||||||
|
context.PushGlobal(_customGlobals);
|
||||||
|
|
||||||
|
var modelGlobals = new ScriptObject();
|
||||||
|
modelGlobals.Import(model, renamer: MemberRenamer);
|
||||||
|
context.PushGlobal(modelGlobals);
|
||||||
|
|
||||||
|
return template.Render(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object? ParseAndEvaluate(string text, object model)
|
public object? ParseAndEvaluate(string text, object model)
|
||||||
|
|||||||
@@ -1,24 +1,32 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using WireMock.Handlers;
|
using Scriban.Runtime;
|
||||||
using WireMock.Types;
|
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
|
using WireMock.Settings;
|
||||||
|
using WireMock.Types;
|
||||||
|
|
||||||
namespace WireMock.Transformers.Scriban;
|
namespace WireMock.Transformers.Scriban;
|
||||||
|
|
||||||
internal class ScribanContextFactory : ITransformerContextFactory
|
internal class ScribanContextFactory : ITransformerContextFactory
|
||||||
{
|
{
|
||||||
private readonly IFileSystemHandler _fileSystemHandler;
|
private readonly WireMockServerSettings _settings;
|
||||||
private readonly TransformerType _transformerType;
|
private readonly TransformerType _transformerType;
|
||||||
|
|
||||||
public ScribanContextFactory(IFileSystemHandler fileSystemHandler, TransformerType transformerType)
|
public ScribanContextFactory(WireMockServerSettings settings, TransformerType transformerType)
|
||||||
{
|
{
|
||||||
_fileSystemHandler = Guard.NotNull(fileSystemHandler);
|
_settings = Guard.NotNull(settings);
|
||||||
_transformerType = Guard.Condition(transformerType, t => t is TransformerType.Scriban or TransformerType.ScribanDotLiquid);
|
_transformerType = Guard.Condition(transformerType, t => t is TransformerType.Scriban or TransformerType.ScribanDotLiquid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITransformerContext Create()
|
public ITransformerContext Create()
|
||||||
{
|
{
|
||||||
return new ScribanContext(_fileSystemHandler, _transformerType);
|
ScriptObject? customGlobals = null;
|
||||||
|
if (_settings.ScribanRegistrationCallback is { } registrationCallback)
|
||||||
|
{
|
||||||
|
customGlobals = new ScriptObject();
|
||||||
|
registrationCallback(customGlobals, _settings.FileSystemHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ScribanContext(_settings.FileSystemHandler, _transformerType, customGlobals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,8 +19,8 @@ internal static class TransformerFactory
|
|||||||
|
|
||||||
case TransformerType.Scriban:
|
case TransformerType.Scriban:
|
||||||
case TransformerType.ScribanDotLiquid:
|
case TransformerType.ScribanDotLiquid:
|
||||||
var factoryDotLiquid = new ScribanContextFactory(settings.FileSystemHandler, transformerType);
|
var factoryScriban = new ScribanContextFactory(settings, transformerType);
|
||||||
return new Transformer(settings, factoryDotLiquid);
|
return new Transformer(settings, factoryScriban);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new NotSupportedException($"{nameof(TransformerType)} '{transformerType}' is not supported.");
|
throw new NotSupportedException($"{nameof(TransformerType)} '{transformerType}' is not supported.");
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ namespace WireMock.WebSockets;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class WireMockWebSocketContext : IWebSocketContext
|
public class WireMockWebSocketContext : IWebSocketContext
|
||||||
{
|
{
|
||||||
|
private readonly IDateTimeUtils _dateTimeUtils;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Guid ConnectionId { get; }
|
public Guid ConnectionId { get; }
|
||||||
|
|
||||||
@@ -50,7 +52,8 @@ public class WireMockWebSocketContext : IWebSocketContext
|
|||||||
WebSocketBuilder builder,
|
WebSocketBuilder builder,
|
||||||
IWireMockMiddlewareOptions options,
|
IWireMockMiddlewareOptions options,
|
||||||
IWireMockMiddlewareLogger logger,
|
IWireMockMiddlewareLogger logger,
|
||||||
IGuidUtils guidUtils
|
IGuidUtils guidUtils,
|
||||||
|
IDateTimeUtils dateTimeUtils
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HttpContext = httpContext;
|
HttpContext = httpContext;
|
||||||
@@ -61,6 +64,7 @@ public class WireMockWebSocketContext : IWebSocketContext
|
|||||||
Builder = builder;
|
Builder = builder;
|
||||||
Options = options;
|
Options = options;
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
|
_dateTimeUtils = dateTimeUtils;
|
||||||
|
|
||||||
ConnectionId = guidUtils.NewGuid();
|
ConnectionId = guidUtils.NewGuid();
|
||||||
}
|
}
|
||||||
@@ -169,7 +173,7 @@ public class WireMockWebSocketContext : IWebSocketContext
|
|||||||
null
|
null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
DateTime = DateTime.UtcNow
|
DateTime = _dateTimeUtils.UtcNow
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -179,7 +183,7 @@ public class WireMockWebSocketContext : IWebSocketContext
|
|||||||
{
|
{
|
||||||
Method = method,
|
Method = method,
|
||||||
BodyData = bodyData,
|
BodyData = bodyData,
|
||||||
DateTime = DateTime.UtcNow
|
DateTime = _dateTimeUtils.UtcNow
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace System.Collections.Generic;
|
namespace System.Collections.Generic;
|
||||||
|
|
||||||
internal static class DictionaryExtensions
|
internal static class DictionaryExtensions
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Microsoft.OpenApi.Reader;
|
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
|
using WireMock.Net.OpenApiParser.Models;
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
|
||||||
|
<!-- See also https://github.com/ravibpatel/ILRepack.Lib.MSBuild.Task/issues/26 -->
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Target Name="ILRepacker" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
|
||||||
|
<ItemGroup>
|
||||||
|
<InputAssemblies Include="$(OutputPath)WireMock.Net.OpenApiParser.dll" />
|
||||||
|
<InputAssemblies Include="@(ReferencePathWithRefAssemblies)" Condition="'%(filename)' == 'Microsoft.OpenApi.YamlReader'" />
|
||||||
|
<InputAssemblies Include="@(ReferencePathWithRefAssemblies)" Condition="'%(filename)' == 'Microsoft.OpenApi'" />
|
||||||
|
<LibraryPath Include="%(ReferencePathWithRefAssemblies.RelativeDir)" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<DoNotInternalizeAssemblies Include="WireMock.Net.OpenApiParser" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ILRepack
|
||||||
|
Parallel="true"
|
||||||
|
Internalize="true"
|
||||||
|
RenameInternalized="true"
|
||||||
|
InternalizeExclude="@(DoNotInternalizeAssemblies)"
|
||||||
|
InputAssemblies="@(InputAssemblies)"
|
||||||
|
LibraryPath="@(LibraryPath)"
|
||||||
|
TargetKind="Dll"
|
||||||
|
KeyFile="../../src/WireMock.Net/WireMock.Net.snk"
|
||||||
|
OutputFile="$(OutputPath)$(AssemblyName).dll"
|
||||||
|
/>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using Microsoft.OpenApi.Reader;
|
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
|
using WireMock.Net.OpenApiParser.Models;
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser;
|
namespace WireMock.Net.OpenApiParser;
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace WireMock.Net.OpenApiParser.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Object containing all diagnostic information related to Open API parsing.
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiDiagnostic
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// List of all errors.
|
||||||
|
/// </summary>
|
||||||
|
public List<OpenApiError> Errors { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of all warnings
|
||||||
|
/// </summary>
|
||||||
|
public List<OpenApiError> Warnings { get; set; } = [];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open API specification version of the document parsed.
|
||||||
|
/// </summary>
|
||||||
|
public OpenApiSpecVersion SpecificationVersion { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace WireMock.Net.OpenApiParser.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Error related to the Open API Document.
|
||||||
|
/// </summary>
|
||||||
|
public class OpenApiError
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the <see cref="OpenApiError"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public OpenApiError(string? pointer, string message)
|
||||||
|
{
|
||||||
|
Pointer = pointer;
|
||||||
|
Message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a copy of an <see cref="OpenApiError"/> object
|
||||||
|
/// </summary>
|
||||||
|
public OpenApiError(OpenApiError error)
|
||||||
|
{
|
||||||
|
Pointer = error.Pointer;
|
||||||
|
Message = error.Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Message explaining the error.
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pointer to the location of the error.
|
||||||
|
/// </summary>
|
||||||
|
public string? Pointer { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the string representation of <see cref="OpenApiError"/>.
|
||||||
|
/// </summary>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Message + (!string.IsNullOrEmpty(Pointer) ? " [" + Pointer + "]" : "");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using MicrosoftOpenApiDiagnostic = Microsoft.OpenApi.Reader.OpenApiDiagnostic;
|
||||||
|
|
||||||
|
namespace WireMock.Net.OpenApiParser.Models;
|
||||||
|
|
||||||
|
internal static class OpenApiMapper
|
||||||
|
{
|
||||||
|
internal static OpenApiDiagnostic? Map(MicrosoftOpenApiDiagnostic? openApiDiagnostic)
|
||||||
|
{
|
||||||
|
if (openApiDiagnostic == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OpenApiDiagnostic
|
||||||
|
{
|
||||||
|
Errors = openApiDiagnostic.Errors.Select(e => new OpenApiError(e.Pointer, e.Message)).ToList(),
|
||||||
|
Warnings = openApiDiagnostic.Warnings.Select(e => new OpenApiError(e.Pointer, e.Message)).ToList(),
|
||||||
|
SpecificationVersion = (OpenApiSpecVersion)openApiDiagnostic.SpecificationVersion
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
namespace WireMock.Net.OpenApiParser.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents versions of OpenAPI specification.
|
||||||
|
/// </summary>
|
||||||
|
public enum OpenApiSpecVersion
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents OpenAPI V2.0 spec
|
||||||
|
/// </summary>
|
||||||
|
OpenApi2_0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents all patches of OpenAPI V3.0 spec (e.g. 3.0.0, 3.0.1)
|
||||||
|
/// </summary>
|
||||||
|
OpenApi3_0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents OpenAPI V3.1 spec
|
||||||
|
/// </summary>
|
||||||
|
OpenApi3_1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents OpenAPI V3.2 spec
|
||||||
|
/// </summary>
|
||||||
|
OpenApi3_2
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.OpenApi;
|
using Microsoft.OpenApi;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser.Settings;
|
namespace WireMock.Net.OpenApiParser.Settings;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.OpenApi;
|
using Microsoft.OpenApi;
|
||||||
using RandomDataGenerator.FieldOptions;
|
using RandomDataGenerator.FieldOptions;
|
||||||
using RandomDataGenerator.Randomizers;
|
using RandomDataGenerator.Randomizers;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using Microsoft.OpenApi;
|
using Microsoft.OpenApi;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser.Settings;
|
namespace WireMock.Net.OpenApiParser.Settings;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser.Utils;
|
namespace WireMock.Net.OpenApiParser.Utils;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json.Nodes;
|
using System.Text.Json.Nodes;
|
||||||
using Microsoft.OpenApi;
|
using Microsoft.OpenApi;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' or '$(TargetFramework)' == 'netstandard2.1' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||||
<PackageReference Include="Required" Version="1.0.0">
|
<PackageReference Include="Required" Version="1.0.0">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
@@ -40,11 +40,27 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<PackageReference Include="RamlToOpenApiConverter" Version="0.40.0" />
|
|
||||||
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19.1" />
|
<PackageReference Include="RandomDataGenerator.Net" Version="1.0.19.1" />
|
||||||
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
<PackageReference Include="Stef.Validation" Version="0.3.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- https://github.com/wiremock/WireMock.Net/issues/1508 -->
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="RamlToOpenApiConverter.SourceOnly" Version="0.50.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
|
||||||
|
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.10.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(Configuration)' == 'Release'">
|
||||||
|
<!-- Keep at version 2.0.43 (https://github.com/ravibpatel/ILRepack.Lib.MSBuild.Task/issues/80) -->
|
||||||
|
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.43" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="Microsoft.OpenApi" Version="3.10.2" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.10.2" PrivateAssets="All" />
|
||||||
|
<PackageReference Include="SharpYaml" Version="2.1.5" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
<ProjectReference Include="..\..\src\WireMock.Net.Abstractions\WireMock.Net.Abstractions.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ using Microsoft.OpenApi.YamlReader;
|
|||||||
using RamlToOpenApiConverter;
|
using RamlToOpenApiConverter;
|
||||||
using WireMock.Admin.Mappings;
|
using WireMock.Admin.Mappings;
|
||||||
using WireMock.Net.OpenApiParser.Mappers;
|
using WireMock.Net.OpenApiParser.Mappers;
|
||||||
|
using WireMock.Net.OpenApiParser.Models;
|
||||||
using WireMock.Net.OpenApiParser.Settings;
|
using WireMock.Net.OpenApiParser.Settings;
|
||||||
|
using OpenApiDiagnostic = WireMock.Net.OpenApiParser.Models.OpenApiDiagnostic;
|
||||||
|
|
||||||
namespace WireMock.Net.OpenApiParser;
|
namespace WireMock.Net.OpenApiParser;
|
||||||
|
|
||||||
@@ -125,7 +127,7 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
|||||||
|
|
||||||
var result = OpenApiDocument.Load(memoryStream, settings: _readerSettings);
|
var result = OpenApiDocument.Load(memoryStream, settings: _readerSettings);
|
||||||
|
|
||||||
diagnostic = result.Diagnostic ?? new OpenApiDiagnostic();
|
diagnostic = OpenApiMapper.Map(result.Diagnostic) ?? new OpenApiDiagnostic();
|
||||||
openApiDocument = result.Document;
|
openApiDocument = result.Document;
|
||||||
return openApiDocument != null && !diagnostic.Errors.Any();
|
return openApiDocument != null && !diagnostic.Errors.Any();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,6 +194,20 @@ public class WireMockServerSettings
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Action<IHandlebars, IFileSystemHandler>? HandlebarsRegistrationCallback { get; set; }
|
public Action<IHandlebars, IFileSystemHandler>? HandlebarsRegistrationCallback { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Action which can be used to add additional Scriban registrations (functions, objects or variables). [Optional]
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The first argument is a <c>Scriban.Runtime.ScriptObject</c> from the <c>Scriban.Signed</c> package.
|
||||||
|
/// It is typed as <see cref="object"/> so that this package does not depend on Scriban.
|
||||||
|
/// Members added to it are available as globals in <see cref="TransformerType.Scriban"/> and <see cref="TransformerType.ScribanDotLiquid"/> templates.
|
||||||
|
/// On a name clash the template model (<c>request</c>, <c>response</c>, <c>mapping</c> and <c>data</c>) takes precedence.
|
||||||
|
/// The action is invoked each time a transformer context is created.
|
||||||
|
/// </remarks>
|
||||||
|
[PublicAPI]
|
||||||
|
[JsonIgnore]
|
||||||
|
public Action<object, IFileSystemHandler>? ScribanRegistrationCallback { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using WireMock.Net.Testcontainers.Utils;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.Facts;
|
||||||
|
|
||||||
|
[ExcludeFromCodeCoverage]
|
||||||
|
public sealed class RunOnDockerFact : FactAttribute
|
||||||
|
{
|
||||||
|
public RunOnDockerFact(
|
||||||
|
[CallerFilePath] string? sourceFilePath = null,
|
||||||
|
[CallerLineNumber] int sourceLineNumber = -1) : base(sourceFilePath, sourceLineNumber)
|
||||||
|
{
|
||||||
|
|
||||||
|
OSPlatform currentPlatform;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentPlatform = TestcontainersUtils.GetImageOSAsync.Value.Result;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Skip = $"Only run test when Docker is installed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -15,7 +15,19 @@ public sealed class RunOnDockerPlatformFact : FactAttribute
|
|||||||
[CallerFilePath] string? sourceFilePath = null,
|
[CallerFilePath] string? sourceFilePath = null,
|
||||||
[CallerLineNumber] int sourceLineNumber = -1) : base(sourceFilePath, sourceLineNumber)
|
[CallerLineNumber] int sourceLineNumber = -1) : base(sourceFilePath, sourceLineNumber)
|
||||||
{
|
{
|
||||||
if (TestcontainersUtils.GetImageOSAsync.Value.Result != OSPlatform.Create(platform))
|
|
||||||
|
OSPlatform currentPlatform;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
currentPlatform = TestcontainersUtils.GetImageOSAsync.Value.Result;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Skip = $"Only run test when Docker is installed.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPlatform != OSPlatform.Create(platform))
|
||||||
{
|
{
|
||||||
Skip = $"Only run test when Docker OS Platform {platform} is used.";
|
Skip = $"Only run test when Docker OS Platform {platform} is used.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,15 @@ public class WireMockMiddlewareTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockMiddleware_Invoke_NoMatch()
|
public async Task WireMockMiddleware_Invoke_NoMatch()
|
||||||
{
|
{
|
||||||
|
// Arrange
|
||||||
|
var inititalDateTime = new DateTime(2027, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
var responseDateTime = new DateTime(2027, 1, 1, 0, 0, 42, DateTimeKind.Utc);
|
||||||
|
|
||||||
|
_dateTimeUtilsMock.Reset();
|
||||||
|
_dateTimeUtilsMock.SetupSequence(d => d.UtcNow)
|
||||||
|
.Returns(inititalDateTime)
|
||||||
|
.Returns(responseDateTime);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await _sut.Invoke(_contextMock.Object);
|
await _sut.Invoke(_contextMock.Object);
|
||||||
|
|
||||||
@@ -115,7 +124,7 @@ public class WireMockMiddlewareTests
|
|||||||
Expression<Func<ResponseMessage, bool>> match = r =>
|
Expression<Func<ResponseMessage, bool>> match = r =>
|
||||||
(int)r.StatusCode! == 404 &&
|
(int)r.StatusCode! == 404 &&
|
||||||
((StatusModel)r.BodyData!.BodyAsJson!).Status == "No matching mapping found" &&
|
((StatusModel)r.BodyData!.BodyAsJson!).Status == "No matching mapping found" &&
|
||||||
r.DateTime == UtcNow;
|
r.DateTime == responseDateTime;
|
||||||
_responseMapperMock.Verify(m => m.MapAsync(It.Is(match), It.IsAny<HttpResponse>()), Times.Once);
|
_responseMapperMock.Verify(m => m.MapAsync(It.Is(match), It.IsAny<HttpResponse>()), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ using WireMock.Util;
|
|||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Scriban.Runtime;
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.ResponseBuilders;
|
namespace WireMock.Net.Tests.ResponseBuilders;
|
||||||
|
|
||||||
@@ -65,5 +67,50 @@ public class ResponseWithScribanTests
|
|||||||
// Assert
|
// Assert
|
||||||
response.Message.BodyData.BodyAsString.Should().Be("test http://localhost/foo /foo POSt");
|
response.Message.BodyData.BodyAsString.Should().Be("test http://localhost/foo /foo POSt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public async Task Response_ProvideResponse_WithScribanRegistrationCallback_UsesCustomFunctionInBodyAndHeaders(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_settings.ScribanRegistrationCallback = (scriptObject, _) =>
|
||||||
|
((ScriptObject)scriptObject).Import("fake_name", new Func<string>(() => "Jane Doe"));
|
||||||
|
|
||||||
|
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp);
|
||||||
|
|
||||||
|
var responseBuilder = Response.Create()
|
||||||
|
.WithBody("{{ fake_name }} {{ request.Path }}")
|
||||||
|
.WithHeader("x-name", "{{ fake_name }}")
|
||||||
|
.WithTransformer(transformerType);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, Mock.Of<HttpContext>(), request, _settings);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.Message.BodyData!.BodyAsString.Should().Be("Jane Doe /foo");
|
||||||
|
response.Message.Headers!["x-name"].Should().ContainSingle().Which.Should().Be("Jane Doe");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public async Task Response_ProvideResponse_WithScribanRegistrationCallback_UsesCustomFunctionInBodyAsJson(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
_settings.WithScribanRegistration((scriptObject, _) => scriptObject.Import("fake_name", new Func<string>(() => "Jane Doe")));
|
||||||
|
|
||||||
|
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", ClientIp);
|
||||||
|
|
||||||
|
var responseBuilder = Response.Create()
|
||||||
|
.WithBodyAsJson(new { name = "{{ fake_name }}", path = "{{ request.Path }}" })
|
||||||
|
.WithTransformer(transformerType);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, Mock.Of<HttpContext>(), request, _settings);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
JsonConvert.SerializeObject(response.Message.BodyData!.BodyAsJson).Should().Be("{\"name\":\"Jane Doe\",\"path\":\"/foo\"}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using Moq;
|
||||||
|
using Scriban.Runtime;
|
||||||
|
using WireMock.Handlers;
|
||||||
|
using WireMock.Settings;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.Settings;
|
||||||
|
|
||||||
|
public class WireMockServerSettingsExtensionsTests
|
||||||
|
{
|
||||||
|
private readonly IFileSystemHandler _fileSystemHandler = Mock.Of<IFileSystemHandler>();
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WithScribanRegistration_SetsCallbackWhichPassesTypedScriptObjectAndFileSystemHandler()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
ScriptObject? receivedScriptObject = null;
|
||||||
|
IFileSystemHandler? receivedFileSystemHandler = null;
|
||||||
|
var settings = new WireMockServerSettings();
|
||||||
|
var scriptObject = new ScriptObject();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = settings.WithScribanRegistration((so, fs) =>
|
||||||
|
{
|
||||||
|
receivedScriptObject = so;
|
||||||
|
receivedFileSystemHandler = fs;
|
||||||
|
});
|
||||||
|
settings.ScribanRegistrationCallback!(scriptObject, _fileSystemHandler);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().BeSameAs(settings);
|
||||||
|
receivedScriptObject.Should().BeSameAs(scriptObject);
|
||||||
|
receivedFileSystemHandler.Should().BeSameAs(_fileSystemHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WithScribanRegistration_WithExistingCallback_InvokesBothInRegistrationOrder()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var calls = new List<string>();
|
||||||
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
ScribanRegistrationCallback = (_, _) => calls.Add("existing")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
settings
|
||||||
|
.WithScribanRegistration((_, _) => calls.Add("first"))
|
||||||
|
.WithScribanRegistration((_, _) => calls.Add("second"));
|
||||||
|
settings.ScribanRegistrationCallback!(new ScriptObject(), _fileSystemHandler);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
calls.Should().Equal("existing", "first", "second");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WithScribanRegistration_WithNullSettings_ThrowsArgumentNullException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
WireMockServerSettings settings = null!;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Action act = () => settings.WithScribanRegistration((_, _) => { });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
act.Should().Throw<ArgumentNullException>();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void WithScribanRegistration_WithNullCallback_ThrowsArgumentNullException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var settings = new WireMockServerSettings();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
Action act = () => settings.WithScribanRegistration(null!);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
act.Should().Throw<ArgumentNullException>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ public class TestcontainersTests(ITestOutputHelper testOutputHelper)
|
|||||||
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
|
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
|
||||||
});
|
});
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_And_StartAsync_and_StopAsync()
|
public async Task WireMockContainer_Build_And_StartAsync_and_StopAsync()
|
||||||
{
|
{
|
||||||
// Act
|
// Act
|
||||||
@@ -57,7 +57,7 @@ public class TestcontainersTests(ITestOutputHelper testOutputHelper)
|
|||||||
await StopAsync(wireMockContainer);
|
await StopAsync(wireMockContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_WithImage_And_StartAsync_and_StopAsync()
|
public async Task WireMockContainer_Build_WithImage_And_StartAsync_and_StopAsync()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -83,7 +83,7 @@ public class TestcontainersTests(ITestOutputHelper testOutputHelper)
|
|||||||
await StopAsync(wireMockContainer);
|
await StopAsync(wireMockContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_WithImageAsText_And_StartAsync_and_StopAsync()
|
public async Task WireMockContainer_Build_WithImageAsText_And_StartAsync_and_StopAsync()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ using Meziantou.Extensions.Logging.Xunit.v3;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using WireMock.Constants;
|
using WireMock.Constants;
|
||||||
using WireMock.Net.Testcontainers;
|
using WireMock.Net.Testcontainers;
|
||||||
|
using WireMock.Net.Tests.Facts;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.Net.Tests.Testcontainers;
|
namespace WireMock.Net.Tests.Testcontainers;
|
||||||
@@ -25,7 +26,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
|
|||||||
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
|
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
|
||||||
});
|
});
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls1()
|
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls1()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -82,7 +83,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls2()
|
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls2()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
@@ -136,7 +137,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionFromJson_UsingGrpcGeneratedClient()
|
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionFromJson_UsingGrpcGeneratedClient()
|
||||||
{
|
{
|
||||||
var wireMockContainer = await Given_WireMockContainerIsStartedForHttpAndGrpcAsync();
|
var wireMockContainer = await Given_WireMockContainerIsStartedForHttpAndGrpcAsync();
|
||||||
@@ -150,7 +151,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
|
|||||||
await StopAsync(wireMockContainer);
|
await StopAsync(wireMockContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient()
|
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient()
|
||||||
{
|
{
|
||||||
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelIsStartedForHttpAndGrpcAsync();
|
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelIsStartedForHttpAndGrpcAsync();
|
||||||
@@ -164,7 +165,7 @@ public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
|
|||||||
await StopAsync(wireMockContainer);
|
await StopAsync(wireMockContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[RunOnDockerFact]
|
||||||
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient_AndWithWatchStaticMappings()
|
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient_AndWithWatchStaticMappings()
|
||||||
{
|
{
|
||||||
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelWithWatchStaticMappingsIsStartedForHttpAndGrpcAsync();
|
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelWithWatchStaticMappingsIsStartedForHttpAndGrpcAsync();
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using Moq;
|
using Moq;
|
||||||
|
using Scriban.Runtime;
|
||||||
using WireMock.Handlers;
|
using WireMock.Handlers;
|
||||||
|
using WireMock.Settings;
|
||||||
using WireMock.Transformers.Scriban;
|
using WireMock.Transformers.Scriban;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
|
|
||||||
@@ -17,23 +19,79 @@ namespace WireMock.Net.Tests.Transformers.Scriban
|
|||||||
public void Create_With_Scriban_TransformerType_Creates_ITransformerContext(TransformerType transformerType)
|
public void Create_With_Scriban_TransformerType_Creates_ITransformerContext(TransformerType transformerType)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var sut = new ScribanContextFactory(_fileSystemHandlerMock.Object, transformerType);
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
FileSystemHandler = _fileSystemHandlerMock.Object
|
||||||
|
};
|
||||||
|
var sut = new ScribanContextFactory(settings, transformerType);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = sut.Create();
|
var result = sut.Create();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
result.Should().NotBeNull();
|
result.Should().NotBeNull();
|
||||||
|
result.FileSystemHandler.Should().BeSameAs(_fileSystemHandlerMock.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Create_With_Invalid_TransformerType_Throws_Exception()
|
public void Create_With_Invalid_TransformerType_Throws_Exception()
|
||||||
{
|
{
|
||||||
|
// Arrange
|
||||||
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
FileSystemHandler = _fileSystemHandlerMock.Object
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
Action action = () => new ScribanContextFactory(_fileSystemHandlerMock.Object, TransformerType.Handlebars);
|
Action action = () => new ScribanContextFactory(settings, TransformerType.Handlebars);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
action.Should().Throw<Exception>();
|
action.Should().Throw<Exception>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public void Create_WithScribanRegistrationCallback_InvokesCallbackOnceWithScriptObjectAndFileSystemHandler(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var calls = new List<(object ScriptObject, IFileSystemHandler FileSystemHandler)>();
|
||||||
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
FileSystemHandler = _fileSystemHandlerMock.Object,
|
||||||
|
ScribanRegistrationCallback = (scriptObject, fileSystemHandler) => calls.Add((scriptObject, fileSystemHandler))
|
||||||
|
};
|
||||||
|
var sut = new ScribanContextFactory(settings, transformerType);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = sut.Create();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
calls.Should().ContainSingle();
|
||||||
|
calls[0].ScriptObject.Should().BeOfType<ScriptObject>();
|
||||||
|
calls[0].FileSystemHandler.Should().BeSameAs(_fileSystemHandlerMock.Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Create_CalledTwice_InvokesScribanRegistrationCallbackWithNewScriptObjectEachTime()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var scriptObjects = new List<object>();
|
||||||
|
var settings = new WireMockServerSettings
|
||||||
|
{
|
||||||
|
FileSystemHandler = _fileSystemHandlerMock.Object,
|
||||||
|
ScribanRegistrationCallback = (scriptObject, _) => scriptObjects.Add(scriptObject)
|
||||||
|
};
|
||||||
|
var sut = new ScribanContextFactory(settings, TransformerType.Scriban);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
sut.Create();
|
||||||
|
sut.Create();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
scriptObjects.Should().HaveCount(2);
|
||||||
|
scriptObjects[0].Should().NotBeSameAs(scriptObjects[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using Moq;
|
||||||
|
using Scriban.Runtime;
|
||||||
|
using WireMock.Handlers;
|
||||||
|
using WireMock.Models;
|
||||||
|
using WireMock.Transformers;
|
||||||
|
using WireMock.Transformers.Scriban;
|
||||||
|
using WireMock.Types;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
|
namespace WireMock.Net.Tests.Transformers.Scriban;
|
||||||
|
|
||||||
|
public class ScribanContextTests
|
||||||
|
{
|
||||||
|
private readonly IFileSystemHandler _fileSystemHandler = Mock.Of<IFileSystemHandler>();
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public void ParseAndRender_WithCustomFunction_RendersFunctionResult(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var customGlobals = new ScriptObject();
|
||||||
|
customGlobals.Import("fake_name", new Func<string>(() => "Jane Doe"));
|
||||||
|
var sut = new ScribanContext(_fileSystemHandler, transformerType, customGlobals);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = sut.ParseAndRender("Hello {{ fake_name }} at {{ request.Path }}", CreateModel());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("Hello Jane Doe at /foo/bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ParseAndRender_Scriban_WithCustomFunctionWithArgument_RendersFunctionResult()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var customGlobals = new ScriptObject();
|
||||||
|
customGlobals.Import("greet", new Func<string, string>(name => $"Hello {name}"));
|
||||||
|
var sut = new ScribanContext(_fileSystemHandler, TransformerType.Scriban, customGlobals);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = sut.ParseAndRender("{{ greet request.Method }}", CreateModel());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("Hello GET");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ParseAndRender_ScribanDotLiquid_WithCustomFunctionAsFilter_RendersFunctionResult()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var customGlobals = new ScriptObject();
|
||||||
|
customGlobals.Import("greet", new Func<string, string>(name => $"Hello {name}"));
|
||||||
|
var sut = new ScribanContext(_fileSystemHandler, TransformerType.ScribanDotLiquid, customGlobals);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = sut.ParseAndRender("{{ request.Method | greet }}", CreateModel());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("Hello GET");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public void ParseAndRender_WithCustomGlobalNamedLikeModelMember_ModelTakesPrecedence(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var customGlobals = new ScriptObject();
|
||||||
|
customGlobals.SetValue("request", "custom", false);
|
||||||
|
customGlobals.SetValue("other", "custom", false);
|
||||||
|
var sut = new ScribanContext(_fileSystemHandler, transformerType, customGlobals);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = sut.ParseAndRender("{{ request.Path }} {{ other }}", CreateModel());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("/foo/bar custom");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public void ParseAndRender_WithCustomGlobalNamedLikeBuiltin_CustomGlobalTakesPrecedence(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var customGlobals = new ScriptObject();
|
||||||
|
customGlobals.SetValue("date", "custom date", false);
|
||||||
|
var sut = new ScribanContext(_fileSystemHandler, transformerType, customGlobals);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = sut.ParseAndRender("{{ date }}", CreateModel());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
result.Should().Be("custom date");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ParseAndRender_WithTemplateAssignment_DoesNotMutateCustomGlobals()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var customGlobals = new ScriptObject();
|
||||||
|
customGlobals.SetValue("x", "custom", false);
|
||||||
|
var sut = new ScribanContext(_fileSystemHandler, TransformerType.Scriban, customGlobals);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var first = sut.ParseAndRender("{{ x = 'assigned'; x }} {{ y = 1; y }}", CreateModel());
|
||||||
|
var second = sut.ParseAndRender("{{ x }}", CreateModel());
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
first.Should().Be("assigned 1");
|
||||||
|
second.Should().Be("custom");
|
||||||
|
customGlobals.Keys.Should().BeEquivalentTo("x");
|
||||||
|
customGlobals["x"].Should().Be("custom");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban, "{{ request.Url }} {{ request.Path }} {{ request.Method }}")]
|
||||||
|
[InlineData(TransformerType.Scriban, "{{ request.PathSegments[1] }} {{ request.Headers.Accept }}")]
|
||||||
|
[InlineData(TransformerType.Scriban, "{{ for s in request.PathSegments }}[{{ s }}]{{ end }}")]
|
||||||
|
[InlineData(TransformerType.Scriban, "{{ request.Body | string.upcase }} {{ data.Id }}")]
|
||||||
|
[InlineData(TransformerType.Scriban, "{{ x = 5; x * 2 }}")]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid, "{{ request.Url }} {{ request.Path }} {{ request.Method }}")]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid, "{% for s in request.PathSegments %}[{{ s }}]{% endfor %}")]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid, "{{ request.Body | upcase }} {{ data.Id }}")]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid, "{% assign x = 5 %}{{ x | times: 2 }}")]
|
||||||
|
public void ParseAndRender_WithEmptyCustomGlobals_RendersSameAsWithoutCustomGlobals(TransformerType transformerType, string template)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var model = CreateModel();
|
||||||
|
var withoutCustomGlobals = new ScribanContext(_fileSystemHandler, transformerType);
|
||||||
|
var withCustomGlobals = new ScribanContext(_fileSystemHandler, transformerType, new ScriptObject());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var expected = withoutCustomGlobals.ParseAndRender(template, model);
|
||||||
|
var result = withCustomGlobals.ParseAndRender(template, model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expected.Should().NotBeNullOrWhiteSpace();
|
||||||
|
result.Should().Be(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TransformModel CreateModel()
|
||||||
|
{
|
||||||
|
var body = new BodyData
|
||||||
|
{
|
||||||
|
BodyAsString = "hello",
|
||||||
|
DetectedBodyType = BodyType.String
|
||||||
|
};
|
||||||
|
var headers = new Dictionary<string, string[]>
|
||||||
|
{
|
||||||
|
{ "Accept", ["application/json"] }
|
||||||
|
};
|
||||||
|
var request = new RequestMessage(new UrlDetails("http://localhost/foo/bar"), "GET", "::1", body, headers);
|
||||||
|
|
||||||
|
return new TransformModel
|
||||||
|
{
|
||||||
|
mapping = Mock.Of<IMapping>(),
|
||||||
|
request = request,
|
||||||
|
data = new { Id = 42 }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ using WireMock.Util;
|
|||||||
|
|
||||||
namespace WireMock.Net.Tests;
|
namespace WireMock.Net.Tests;
|
||||||
|
|
||||||
|
[Collection(nameof(WireMockServerProxyTests))]
|
||||||
public class WireMockServerProxyTests
|
public class WireMockServerProxyTests
|
||||||
{
|
{
|
||||||
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
|
||||||
@@ -58,12 +59,13 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_AdminFalse_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
|
public async Task WireMockServer_Proxy_AdminFalse_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var cancellationToken = TestContext.Current.CancellationToken;
|
var cancellationToken = TestContext.Current.CancellationToken;
|
||||||
var settings = new WireMockServerSettings
|
var settings = new WireMockServerSettings
|
||||||
{
|
{
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "http://www.google.com",
|
Url = target.Url!,
|
||||||
SaveMapping = true,
|
SaveMapping = true,
|
||||||
SaveMappingToFile = false,
|
SaveMappingToFile = false,
|
||||||
ExcludedHeaders = ["Connection"] // Needed for .NET 4.5.x and 4.6.x
|
ExcludedHeaders = ["Connection"] // Needed for .NET 4.5.x and 4.6.x
|
||||||
@@ -92,12 +94,13 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_AdminTrue_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
|
public async Task WireMockServer_Proxy_AdminTrue_With_SaveMapping_Is_True_And_SaveMappingToFile_Is_False_Should_AddInternalMappingOnly()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var cancellationToken = TestContext.Current.CancellationToken;
|
var cancellationToken = TestContext.Current.CancellationToken;
|
||||||
var settings = new WireMockServerSettings
|
var settings = new WireMockServerSettings
|
||||||
{
|
{
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "http://www.google.com",
|
Url = target.Url!,
|
||||||
SaveMapping = true,
|
SaveMapping = true,
|
||||||
SaveMappingToFile = false,
|
SaveMappingToFile = false,
|
||||||
ExcludedHeaders = ["Connection"] // Needed for .NET 4.5.x and 4.6.x
|
ExcludedHeaders = ["Connection"] // Needed for .NET 4.5.x and 4.6.x
|
||||||
@@ -184,6 +187,7 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_With_SaveMapping_Is_False_And_SaveMappingToFile_Is_True_ShouldSaveMappingToFile()
|
public async Task WireMockServer_Proxy_With_SaveMapping_Is_False_And_SaveMappingToFile_Is_True_ShouldSaveMappingToFile()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
||||||
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
||||||
|
|
||||||
@@ -191,7 +195,7 @@ public class WireMockServerProxyTests
|
|||||||
{
|
{
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "http://www.google.com",
|
Url = target.Url!,
|
||||||
SaveMapping = false,
|
SaveMapping = false,
|
||||||
SaveMappingToFile = true
|
SaveMappingToFile = true
|
||||||
},
|
},
|
||||||
@@ -220,6 +224,7 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_With_SaveMappingForStatusCodePattern_Is_False_Should_Not_SaveMapping()
|
public async Task WireMockServer_Proxy_With_SaveMappingForStatusCodePattern_Is_False_Should_Not_SaveMapping()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
||||||
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
||||||
|
|
||||||
@@ -227,7 +232,7 @@ public class WireMockServerProxyTests
|
|||||||
{
|
{
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "http://www.google.com",
|
Url = target.Url!,
|
||||||
SaveMapping = true,
|
SaveMapping = true,
|
||||||
SaveMappingToFile = true,
|
SaveMappingToFile = true,
|
||||||
SaveMappingForStatusCodePattern = "999" // Just make sure that we don't want this mapping
|
SaveMappingForStatusCodePattern = "999" // Just make sure that we don't want this mapping
|
||||||
@@ -257,6 +262,7 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_With_DoNotSaveMappingForHttpMethod_Should_Not_SaveMapping()
|
public async Task WireMockServer_Proxy_With_DoNotSaveMappingForHttpMethod_Should_Not_SaveMapping()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
var fileSystemHandlerMock = new Mock<IFileSystemHandler>();
|
||||||
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
fileSystemHandlerMock.Setup(f => f.GetMappingFolder()).Returns("m");
|
||||||
|
|
||||||
@@ -264,7 +270,7 @@ public class WireMockServerProxyTests
|
|||||||
{
|
{
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "http://www.google.com",
|
Url = target.Url!,
|
||||||
SaveMapping = true,
|
SaveMapping = true,
|
||||||
SaveMappingToFile = true,
|
SaveMappingToFile = true,
|
||||||
SaveMappingSettings = new ProxySaveMappingSettings
|
SaveMappingSettings = new ProxySaveMappingSettings
|
||||||
@@ -297,11 +303,12 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_Should_log_proxied_requests()
|
public async Task WireMockServer_Proxy_Should_log_proxied_requests()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var settings = new WireMockServerSettings
|
var settings = new WireMockServerSettings
|
||||||
{
|
{
|
||||||
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
ProxyAndRecordSettings = new ProxyAndRecordSettings
|
||||||
{
|
{
|
||||||
Url = "http://www.google.com",
|
Url = target.Url!,
|
||||||
SaveMapping = true,
|
SaveMapping = true,
|
||||||
SaveMappingToFile = false
|
SaveMappingToFile = false
|
||||||
}
|
}
|
||||||
@@ -327,12 +334,13 @@ public class WireMockServerProxyTests
|
|||||||
public async Task WireMockServer_Proxy_Should_proxy_responses()
|
public async Task WireMockServer_Proxy_Should_proxy_responses()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
|
using var target = StartProxyTargetServer();
|
||||||
var cancellationToken = TestContext.Current.CancellationToken;
|
var cancellationToken = TestContext.Current.CancellationToken;
|
||||||
string path = $"/prx_{Guid.NewGuid()}";
|
string path = $"/prx_{Guid.NewGuid()}";
|
||||||
var server = WireMockServer.Start();
|
var server = WireMockServer.Start();
|
||||||
server
|
server
|
||||||
.Given(Request.Create().WithPath(path))
|
.Given(Request.Create().WithPath(path))
|
||||||
.RespondWith(Response.Create().WithProxy("http://www.google.com"));
|
.RespondWith(Response.Create().WithProxy(target.Url!));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var requestMessage = new HttpRequestMessage
|
var requestMessage = new HttpRequestMessage
|
||||||
@@ -348,7 +356,7 @@ public class WireMockServerProxyTests
|
|||||||
// Assert
|
// Assert
|
||||||
server.Mappings.Should().HaveCount(1);
|
server.Mappings.Should().HaveCount(1);
|
||||||
server.LogEntries.Should().HaveCount(1);
|
server.LogEntries.Should().HaveCount(1);
|
||||||
content.Should().Contain("google");
|
content.Should().Be(ProxyTargetBody);
|
||||||
|
|
||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
@@ -946,6 +954,20 @@ public class WireMockServerProxyTests
|
|||||||
server.LogEntries.Should().HaveCount(1);
|
server.LogEntries.Should().HaveCount(1);
|
||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const string ProxyTargetBody = "response from proxy target";
|
||||||
|
|
||||||
|
private static WireMockServer StartProxyTargetServer()
|
||||||
|
{
|
||||||
|
var target = WireMockServer.Start();
|
||||||
|
target
|
||||||
|
.Given(Request.Create().WithPath("/*"))
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithStatusCode(HttpStatusCode.OK)
|
||||||
|
.WithBody(ProxyTargetBody));
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -46,5 +46,3 @@ public class WireMockServerProxy2Tests
|
|||||||
serverAsProxy.Dispose();
|
serverAsProxy.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
|
||||||
|
using Scriban.Runtime;
|
||||||
using WireMock.Authentication;
|
using WireMock.Authentication;
|
||||||
using WireMock.Constants;
|
using WireMock.Constants;
|
||||||
using WireMock.Logging;
|
using WireMock.Logging;
|
||||||
using WireMock.Owin;
|
using WireMock.Owin;
|
||||||
|
using WireMock.RequestBuilders;
|
||||||
|
using WireMock.ResponseBuilders;
|
||||||
using WireMock.Server;
|
using WireMock.Server;
|
||||||
using WireMock.Settings;
|
using WireMock.Settings;
|
||||||
|
using WireMock.Types;
|
||||||
|
|
||||||
namespace WireMock.Net.Tests;
|
namespace WireMock.Net.Tests;
|
||||||
|
|
||||||
@@ -228,5 +233,33 @@ public class WireMockServerSettingsTests
|
|||||||
options.ActivityTracingOptions.Should().BeNull();
|
options.ActivityTracingOptions.Should().BeNull();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData(TransformerType.Scriban)]
|
||||||
|
[InlineData(TransformerType.ScribanDotLiquid)]
|
||||||
|
public async Task WireMockServer_WireMockServerSettings_ScribanRegistrationCallback_IsUsedInResponseTemplate(TransformerType transformerType)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var cancellationToken = TestContext.Current.CancellationToken;
|
||||||
|
var path = $"/scriban_{Guid.NewGuid()}";
|
||||||
|
using var server = WireMockServer.Start(new WireMockServerSettings
|
||||||
|
{
|
||||||
|
ScribanRegistrationCallback = (scriptObject, _) =>
|
||||||
|
((ScriptObject)scriptObject).Import("fake_name", new Func<string>(() => "Jane Doe"))
|
||||||
|
});
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create().WithPath(path).UsingGet())
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBody("{{ fake_name }} {{ request.Path }}")
|
||||||
|
.WithTransformer(transformerType)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await new HttpClient().GetStringAsync(server.Url + path, cancellationToken);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.Should().Be($"Jane Doe {path}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,6 +640,8 @@ public partial class WireMockServerTests(ITestOutputHelper testOutputHelper)
|
|||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockServer_Should_respond_to_ipv6_loopback()
|
public async Task WireMockServer_Should_respond_to_ipv6_loopback()
|
||||||
{
|
{
|
||||||
|
Assert.SkipUnless(Socket.OSSupportsIPv6, "IPv6 is not supported on this machine.");
|
||||||
|
|
||||||
// Assign
|
// Assign
|
||||||
var server = WireMockServer.Start();
|
var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user