This commit is contained in:
Stef Heyenrath
2026-02-22 16:24:27 +01:00
parent 13693bf76e
commit c35aee53eb
9 changed files with 40 additions and 43 deletions

View File

@@ -24,8 +24,8 @@ jobs:
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
# - name: 'WireMock.Net.TUnitTests' - name: 'WireMock.Net.TUnitTests'
# run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release run: dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release
- name: 'WireMock.Net.Tests' - name: 'WireMock.Net.Tests'
run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0 run: dotnet test --project './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
@@ -63,8 +63,5 @@ jobs:
- name: 'WireMock.Net.Middleware.Tests' - name: 'WireMock.Net.Middleware.Tests'
run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release run: dotnet test --project './test/WireMock.Net.Middleware.Tests/WireMock.Net.Middleware.Tests.csproj' -c Release
- name: Install .NET Aspire workload
run: dotnet workload install aspire
- name: 'WireMock.Net.Aspire.Tests' - name: 'WireMock.Net.Aspire.Tests'
run: dotnet test --project './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release run: dotnet test --project './test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj' -c Release

View File

@@ -64,6 +64,7 @@ internal partial class AspNetCoreSelfHost
services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>(); services.AddSingleton<IOwinRequestMapper, OwinRequestMapper>();
services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>(); services.AddSingleton<IOwinResponseMapper, OwinResponseMapper>();
services.AddSingleton<IGuidUtils, GuidUtils>(); services.AddSingleton<IGuidUtils, GuidUtils>();
services.AddSingleton<IDateTimeUtils, DateTimeUtils>();
services.AddSingleton<LogEntryMapper>(); services.AddSingleton<LogEntryMapper>();
services.AddSingleton<IWireMockMiddlewareLogger, WireMockMiddlewareLogger>(); services.AddSingleton<IWireMockMiddlewareLogger, WireMockMiddlewareLogger>();

View File

@@ -23,7 +23,8 @@ internal class WireMockMiddleware(
IOwinResponseMapper responseMapper, IOwinResponseMapper responseMapper,
IMappingMatcher mappingMatcher, IMappingMatcher mappingMatcher,
IWireMockMiddlewareLogger logger, IWireMockMiddlewareLogger logger,
IGuidUtils guidUtils IGuidUtils guidUtils,
IDateTimeUtils dateTimeUtils
) )
{ {
private readonly object _lock = new(); private readonly object _lock = new();
@@ -47,6 +48,7 @@ internal class WireMockMiddleware(
ctx.Items[nameof(IWireMockMiddlewareOptions)] = options; ctx.Items[nameof(IWireMockMiddlewareOptions)] = options;
ctx.Items[nameof(IWireMockMiddlewareLogger)] = logger; ctx.Items[nameof(IWireMockMiddlewareLogger)] = logger;
ctx.Items[nameof(IGuidUtils)] = guidUtils; ctx.Items[nameof(IGuidUtils)] = guidUtils;
ctx.Items[nameof(IDateTimeUtils)] = dateTimeUtils;
var request = await requestMapper.MapAsync(ctx, options).ConfigureAwait(false); var request = await requestMapper.MapAsync(ctx, options).ConfigureAwait(false);

View File

@@ -9,9 +9,10 @@ namespace WireMock.ResponseProviders;
/// </summary> /// </summary>
internal class WebSocketHandledResponse : ResponseMessage internal class WebSocketHandledResponse : ResponseMessage
{ {
public WebSocketHandledResponse() public WebSocketHandledResponse(DateTime dateTime)
{ {
// 101 Switching Protocols // 101 Switching Protocols
StatusCode = (int)HttpStatusCode.SwitchingProtocols; StatusCode = (int)HttpStatusCode.SwitchingProtocols;
DateTime = dateTime;
} }
} }

View File

@@ -16,7 +16,7 @@ using WireMock.WebSockets;
namespace WireMock.ResponseProviders; namespace WireMock.ResponseProviders;
internal class WebSocketResponseProvider(WebSocketBuilder builder) : IResponseProvider internal class WebSocketResponseProvider(WebSocketBuilder builder, IGuidUtils guidUtils, IDateTimeUtils dateTimeUtils) : IResponseProvider
{ {
public async Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync( public async Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(
IMapping mapping, IMapping mapping,
@@ -30,6 +30,16 @@ internal class WebSocketResponseProvider(WebSocketBuilder builder) : IResponsePr
return (ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "Bad Request: Not a WebSocket upgrade request"), null); return (ResponseMessageBuilder.Create(HttpStatusCode.BadRequest, "Bad Request: Not a WebSocket upgrade request"), null);
} }
if (!context.Items.TryGetValue<IWireMockMiddlewareOptions>(nameof(IWireMockMiddlewareOptions), out var options))
{
throw new InvalidOperationException("IWireMockMiddlewareOptions not found in HttpContext.Items");
}
if (!context.Items.TryGetValue<IWireMockMiddlewareLogger>(nameof(IWireMockMiddlewareLogger), out var logger))
{
throw new InvalidOperationException("IWireMockMiddlewareLogger not found in HttpContext.Items");
}
try try
{ {
// Accept the WebSocket connection // Accept the WebSocket connection
@@ -45,21 +55,6 @@ internal class WebSocketResponseProvider(WebSocketBuilder builder) : IResponsePr
var webSocket = await context.WebSockets.AcceptWebSocketAsync(builder.AcceptProtocol).ConfigureAwait(false); var webSocket = await context.WebSockets.AcceptWebSocketAsync(builder.AcceptProtocol).ConfigureAwait(false);
#endif #endif
if (!context.Items.TryGetValue<IWireMockMiddlewareOptions>(nameof(IWireMockMiddlewareOptions), out var options))
{
throw new InvalidOperationException("IWireMockMiddlewareOptions not found in HttpContext.Items");
}
if (!context.Items.TryGetValue<IWireMockMiddlewareLogger>(nameof(IWireMockMiddlewareLogger), out var logger))
{
throw new InvalidOperationException("IWireMockMiddlewareLogger not found in HttpContext.Items");
}
if (!context.Items.TryGetValue<IGuidUtils>(nameof(IGuidUtils), out var guidUtils))
{
throw new InvalidOperationException("IGuidUtils not found in HttpContext.Items");
}
// Get or create registry from options // Get or create registry from options
var registry = builder.IsBroadcast var registry = builder.IsBroadcast
? options.WebSocketRegistries.GetOrAdd(mapping.Guid, _ => new WebSocketConnectionRegistry()) ? options.WebSocketRegistries.GetOrAdd(mapping.Guid, _ => new WebSocketConnectionRegistry())
@@ -109,7 +104,7 @@ internal class WebSocketResponseProvider(WebSocketBuilder builder) : IResponsePr
} }
// Return special marker to indicate WebSocket was handled // Return special marker to indicate WebSocket was handled
return (new WebSocketHandledResponse(), null); return (new WebSocketHandledResponse(dateTimeUtils.UtcNow), null);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -122,7 +117,7 @@ internal class WebSocketResponseProvider(WebSocketBuilder builder) : IResponsePr
} }
// Already upgraded - return marker // Already upgraded - return marker
return (new WebSocketHandledResponse(), null); return (new WebSocketHandledResponse(dateTimeUtils.UtcNow), null);
} }
} }

View File

@@ -2,8 +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;
using System.Collections.Generic;
using System.Net; using System.Net;
using Stef.Validation; using Stef.Validation;
using WireMock.Matchers.Request; using WireMock.Matchers.Request;
@@ -25,6 +23,8 @@ internal class RespondWithAProvider : IRespondWithAProvider
private readonly IRequestMatcher _requestMatcher; private readonly IRequestMatcher _requestMatcher;
private readonly WireMockServerSettings _settings; private readonly WireMockServerSettings _settings;
private readonly IDateTimeUtils _dateTimeUtils; private readonly IDateTimeUtils _dateTimeUtils;
private readonly IGuidUtils _guidUtils;
private readonly bool _saveToFile; private readonly bool _saveToFile;
private int _priority; private int _priority;
@@ -49,16 +49,7 @@ internal class RespondWithAProvider : IRespondWithAProvider
public IdOrTexts? ProtoDefinition { get; private set; } public IdOrTexts? ProtoDefinition { get; private set; }
/// <summary> internal RespondWithAProvider(
/// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.
/// </summary>
/// <param name="registrationCallback">The registration callback.</param>
/// <param name="requestMatcher">The request matcher.</param>
/// <param name="settings">The WireMockServerSettings.</param>
/// <param name="guidUtils">GuidUtils to make unit testing possible.</param>
/// <param name="dateTimeUtils">DateTimeUtils to make unit testing possible.</param>
/// <param name="saveToFile">Optional boolean to indicate if this mapping should be saved as static mapping file.</param>
public RespondWithAProvider(
RegistrationCallback registrationCallback, RegistrationCallback registrationCallback,
IRequestMatcher requestMatcher, IRequestMatcher requestMatcher,
WireMockServerSettings settings, WireMockServerSettings settings,
@@ -71,6 +62,8 @@ internal class RespondWithAProvider : IRespondWithAProvider
_requestMatcher = Guard.NotNull(requestMatcher); _requestMatcher = Guard.NotNull(requestMatcher);
_settings = Guard.NotNull(settings); _settings = Guard.NotNull(settings);
_dateTimeUtils = Guard.NotNull(dateTimeUtils); _dateTimeUtils = Guard.NotNull(dateTimeUtils);
_guidUtils = Guard.NotNull(guidUtils);
_saveToFile = saveToFile; _saveToFile = saveToFile;
Guid = guidUtils.NewGuid(); Guid = guidUtils.NewGuid();
@@ -82,7 +75,11 @@ internal class RespondWithAProvider : IRespondWithAProvider
if (provider is Response response && response.WebSocketBuilder != null) if (provider is Response response && response.WebSocketBuilder != null)
{ {
// If the provider is a Response with a WebSocketBuilder, we need to use a WebSocketResponseProvider instead. // If the provider is a Response with a WebSocketBuilder, we need to use a WebSocketResponseProvider instead.
provider = new WebSocketResponseProvider(response.WebSocketBuilder); provider = new WebSocketResponseProvider(
response.WebSocketBuilder,
_guidUtils,
_dateTimeUtils
);
} }
var mapping = new Mapping var mapping = new Mapping

View File

@@ -1,7 +1,5 @@
// Copyright © WireMock.Net // Copyright © WireMock.Net
using System;
namespace WireMock.Util; namespace WireMock.Util;
internal interface IDateTimeUtils internal interface IDateTimeUtils

View File

@@ -26,6 +26,7 @@ namespace WireMock.Net.Tests.Owin;
public class WireMockMiddlewareTests public class WireMockMiddlewareTests
{ {
private static readonly Guid NewGuid = new("98fae52e-76df-47d9-876f-2ee32e931d9b"); private static readonly Guid NewGuid = new("98fae52e-76df-47d9-876f-2ee32e931d9b");
private static readonly DateTime UtcNow = new(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc);
private static readonly DateTime UpdatedAt = new(2022, 12, 4); private static readonly DateTime UpdatedAt = new(2022, 12, 4);
private readonly ConcurrentDictionary<Guid, IMapping> _mappings = new(); private readonly ConcurrentDictionary<Guid, IMapping> _mappings = new();
@@ -37,6 +38,7 @@ public class WireMockMiddlewareTests
private readonly Mock<IRequestMatchResult> _requestMatchResultMock; private readonly Mock<IRequestMatchResult> _requestMatchResultMock;
private readonly Mock<HttpContext> _contextMock; private readonly Mock<HttpContext> _contextMock;
private readonly Mock<IGuidUtils> _guidUtilsMock; private readonly Mock<IGuidUtils> _guidUtilsMock;
private readonly Mock<IDateTimeUtils> _dateTimeUtilsMock;
private readonly WireMockMiddleware _sut; private readonly WireMockMiddleware _sut;
@@ -47,6 +49,9 @@ public class WireMockMiddlewareTests
_guidUtilsMock = new Mock<IGuidUtils>(); _guidUtilsMock = new Mock<IGuidUtils>();
_guidUtilsMock.Setup(g => g.NewGuid()).Returns(NewGuid); _guidUtilsMock.Setup(g => g.NewGuid()).Returns(NewGuid);
_dateTimeUtilsMock = new Mock<IDateTimeUtils>();
_dateTimeUtilsMock.Setup(d => d.UtcNow).Returns(UtcNow);
_optionsMock = new Mock<IWireMockMiddlewareOptions>(); _optionsMock = new Mock<IWireMockMiddlewareOptions>();
_optionsMock.SetupAllProperties(); _optionsMock.SetupAllProperties();
_optionsMock.Setup(o => o.Mappings).Returns(_mappings); _optionsMock.Setup(o => o.Mappings).Returns(_mappings);
@@ -85,7 +90,8 @@ public class WireMockMiddlewareTests
_responseMapperMock.Object, _responseMapperMock.Object,
_matcherMock.Object, _matcherMock.Object,
wireMockMiddlewareLoggerMock.Object, wireMockMiddlewareLoggerMock.Object,
_guidUtilsMock.Object _guidUtilsMock.Object,
_dateTimeUtilsMock.Object
); );
} }

View File

@@ -704,7 +704,7 @@ public class WebSocketIntegrationTests(ITestOutputHelper output, ITestContextAcc
.WithWebSocketUpgrade() .WithWebSocketUpgrade()
) )
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithWebSocketProxy(exampleEchoServer.Url!) .WithWebSocketProxy($"{exampleEchoServer.Url}/ws/target")
); );
using var client = new ClientWebSocket(); using var client = new ClientWebSocket();
@@ -759,7 +759,7 @@ public class WebSocketIntegrationTests(ITestOutputHelper output, ITestContextAcc
.WithWebSocketUpgrade() .WithWebSocketUpgrade()
) )
.RespondWith(Response.Create() .RespondWith(Response.Create()
.WithWebSocketProxy(exampleEchoServer.Url!) .WithWebSocketProxy($"{exampleEchoServer.Url}/ws/target")
); );
using var client = new ClientWebSocket(); using var client = new ClientWebSocket();