Add unit tests for RabbitMq and Udp transport servers and clients
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Implemented comprehensive unit tests for RabbitMqTransportServer, covering constructor, disposal, connection management, event handlers, and exception handling. - Added configuration tests for RabbitMqTransportServer to validate SSL, durable queues, auto-recovery, and custom virtual host options. - Created unit tests for UdpFrameProtocol, including frame parsing and serialization, header size validation, and round-trip data preservation. - Developed tests for UdpTransportClient, focusing on connection handling, event subscriptions, and exception scenarios. - Established tests for UdpTransportServer, ensuring proper start/stop behavior, connection state management, and event handling. - Included tests for UdpTransportOptions to verify default values and modification capabilities. - Enhanced service registration tests for Udp transport services in the dependency injection container.
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Moq;
|
||||
using StellaOps.Gateway.WebService.Middleware;
|
||||
using StellaOps.Router.Common.Abstractions;
|
||||
using StellaOps.Router.Common.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Gateway.WebService.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for <see cref="EndpointResolutionMiddleware"/>.
|
||||
/// </summary>
|
||||
public sealed class EndpointResolutionMiddlewareTests
|
||||
{
|
||||
private readonly Mock<IGlobalRoutingState> _routingStateMock;
|
||||
private readonly Mock<RequestDelegate> _nextMock;
|
||||
private bool _nextCalled;
|
||||
|
||||
public EndpointResolutionMiddlewareTests()
|
||||
{
|
||||
_routingStateMock = new Mock<IGlobalRoutingState>();
|
||||
_nextMock = new Mock<RequestDelegate>();
|
||||
_nextMock.Setup(n => n(It.IsAny<HttpContext>()))
|
||||
.Callback(() => _nextCalled = true)
|
||||
.Returns(Task.CompletedTask);
|
||||
}
|
||||
|
||||
private EndpointResolutionMiddleware CreateMiddleware()
|
||||
{
|
||||
return new EndpointResolutionMiddleware(_nextMock.Object);
|
||||
}
|
||||
|
||||
private static HttpContext CreateHttpContext(string method = "GET", string path = "/api/test")
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Method = method;
|
||||
context.Request.Path = path;
|
||||
context.Response.Body = new MemoryStream();
|
||||
return context;
|
||||
}
|
||||
|
||||
private static EndpointDescriptor CreateEndpoint(
|
||||
string serviceName = "test-service",
|
||||
string method = "GET",
|
||||
string path = "/api/test")
|
||||
{
|
||||
return new EndpointDescriptor
|
||||
{
|
||||
ServiceName = serviceName,
|
||||
Version = "1.0.0",
|
||||
Method = method,
|
||||
Path = path
|
||||
};
|
||||
}
|
||||
|
||||
#region Matching Endpoint Tests
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithMatchingEndpoint_SetsHttpContextItem()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint = CreateEndpoint();
|
||||
var context = CreateHttpContext();
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/test"))
|
||||
.Returns(endpoint);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeTrue();
|
||||
context.Items[RouterHttpContextKeys.EndpointDescriptor].Should().Be(endpoint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithMatchingEndpoint_CallsNext()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint = CreateEndpoint();
|
||||
var context = CreateHttpContext();
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/test"))
|
||||
.Returns(endpoint);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeTrue();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unknown Path Tests
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithUnknownPath_Returns404()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var context = CreateHttpContext(path: "/api/unknown");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/unknown"))
|
||||
.Returns((EndpointDescriptor?)null);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeFalse();
|
||||
context.Response.StatusCode.Should().Be(StatusCodes.Status404NotFound);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithUnknownPath_WritesErrorResponse()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var context = CreateHttpContext(path: "/api/unknown");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/unknown"))
|
||||
.Returns((EndpointDescriptor?)null);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
context.Response.Body.Seek(0, SeekOrigin.Begin);
|
||||
using var reader = new StreamReader(context.Response.Body);
|
||||
var responseBody = await reader.ReadToEndAsync();
|
||||
|
||||
responseBody.Should().Contain("not found");
|
||||
responseBody.Should().Contain("/api/unknown");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region HTTP Method Tests
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithPostMethod_ResolvesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint = CreateEndpoint(method: "POST");
|
||||
var context = CreateHttpContext(method: "POST");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("POST", "/api/test"))
|
||||
.Returns(endpoint);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeTrue();
|
||||
context.Items[RouterHttpContextKeys.EndpointDescriptor].Should().Be(endpoint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithDeleteMethod_ResolvesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint = CreateEndpoint(method: "DELETE", path: "/api/users/123");
|
||||
var context = CreateHttpContext(method: "DELETE", path: "/api/users/123");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("DELETE", "/api/users/123"))
|
||||
.Returns(endpoint);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithWrongMethod_Returns404()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var context = CreateHttpContext(method: "DELETE", path: "/api/test");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("DELETE", "/api/test"))
|
||||
.Returns((EndpointDescriptor?)null);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeFalse();
|
||||
context.Response.StatusCode.Should().Be(StatusCodes.Status404NotFound);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Path Variations Tests
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithParameterizedPath_ResolvesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint = CreateEndpoint(path: "/api/users/{id}");
|
||||
var context = CreateHttpContext(path: "/api/users/123");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/users/123"))
|
||||
.Returns(endpoint);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeTrue();
|
||||
context.Items[RouterHttpContextKeys.EndpointDescriptor].Should().Be(endpoint);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithRootPath_ResolvesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint = CreateEndpoint(path: "/");
|
||||
var context = CreateHttpContext(path: "/");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/"))
|
||||
.Returns(endpoint);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_nextCalled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_WithEmptyPath_PassesEmptyStringToRouting()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var context = CreateHttpContext(path: "");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", ""))
|
||||
.Returns((EndpointDescriptor?)null);
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
_routingStateMock.Verify(r => r.ResolveEndpoint("GET", ""), Times.Once);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Multiple Calls Tests
|
||||
|
||||
[Fact]
|
||||
public async Task Invoke_MultipleCalls_EachResolvesIndependently()
|
||||
{
|
||||
// Arrange
|
||||
var middleware = CreateMiddleware();
|
||||
var endpoint1 = CreateEndpoint(path: "/api/users");
|
||||
var endpoint2 = CreateEndpoint(path: "/api/items");
|
||||
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/users"))
|
||||
.Returns(endpoint1);
|
||||
_routingStateMock.Setup(r => r.ResolveEndpoint("GET", "/api/items"))
|
||||
.Returns(endpoint2);
|
||||
|
||||
var context1 = CreateHttpContext(path: "/api/users");
|
||||
var context2 = CreateHttpContext(path: "/api/items");
|
||||
|
||||
// Act
|
||||
await middleware.Invoke(context1, _routingStateMock.Object);
|
||||
await middleware.Invoke(context2, _routingStateMock.Object);
|
||||
|
||||
// Assert
|
||||
context1.Items[RouterHttpContextKeys.EndpointDescriptor].Should().Be(endpoint1);
|
||||
context2.Items[RouterHttpContextKeys.EndpointDescriptor].Should().Be(endpoint2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user