Add UnitTests and made code testable with DI
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using TinfoilVibeServer.Authentication;
|
||||
using TinfoilVibeServer.Middleware;
|
||||
|
||||
namespace TinfoilVibeServerTest.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class BasicAuthMiddlewareTests
|
||||
{
|
||||
private Mock<ILogger<BasicAuthMiddleware>> _loggerMock;
|
||||
private Mock<IAuthStore> _authMock;
|
||||
private BasicAuthMiddleware _middleware;
|
||||
private RequestDelegate _next;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_loggerMock = new Mock<ILogger<BasicAuthMiddleware>>();
|
||||
_authMock = new Mock<IAuthStore>();
|
||||
_next = (HttpContext ctx) => Task.CompletedTask;
|
||||
|
||||
_middleware = new BasicAuthMiddleware(_next);
|
||||
}
|
||||
|
||||
private HttpContext CreateContext(string authHeader = null, string ip = "127.0.0.1", int? uid = null)
|
||||
{
|
||||
var ctx = new DefaultHttpContext();
|
||||
ctx.Connection.RemoteIpAddress = IPAddress.Parse(ip);
|
||||
|
||||
if (!string.IsNullOrEmpty(authHeader))
|
||||
{
|
||||
ctx.Request.Headers["Authorization"] = authHeader;
|
||||
}
|
||||
|
||||
if (uid!= null)
|
||||
{
|
||||
ctx.Request.Headers["UID"] = uid.ToString();
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task InvokeAsync_NoAuthHeader_ShouldReturn401()
|
||||
{
|
||||
// Arrange
|
||||
var ctx = CreateContext();
|
||||
|
||||
// Act
|
||||
await _middleware.InvokeAsync(ctx, _authMock.Object, _loggerMock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.That(ctx.Response.StatusCode, Is.EqualTo(StatusCodes.Status401Unauthorized));
|
||||
_loggerMock.Verify(l => l.Log(
|
||||
LogLevel.Warning,
|
||||
It.IsAny<EventId>(),
|
||||
It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("Missing Authorization header")),
|
||||
null,
|
||||
It.IsAny<Func<It.IsAnyType, Exception, string>>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task InvokeAsync_BlacklistedIP_ShouldReturn403()
|
||||
{
|
||||
// Arrange
|
||||
var ctx = CreateContext("Basic dXNlcjpwYXNz");
|
||||
|
||||
_authMock.Setup(a => a.IsIPBlacklisted("127.0.0.1")).Returns(true);
|
||||
|
||||
// Act
|
||||
|
||||
await _middleware.InvokeAsync(ctx, _authMock.Object, _loggerMock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.That(ctx.Response.StatusCode, Is.EqualTo(StatusCodes.Status403Forbidden));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task InvokeAsync_ValidCredentials_ShouldCallNext()
|
||||
{
|
||||
// Arrange
|
||||
var user = "alice";
|
||||
var pw = "secret";
|
||||
var uid = 1234;
|
||||
var header = $"Basic {Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pw}"))}";
|
||||
|
||||
var ip = "127.0.0.1";
|
||||
var ctx = CreateContext(header,ip, uid);
|
||||
|
||||
string? error;
|
||||
_authMock.Setup(a =>
|
||||
a.TryValidate(user, pw, uid, ip, out error))
|
||||
.Returns(true);
|
||||
|
||||
bool nextCalled = false;
|
||||
_next = (HttpContext _) => { nextCalled = true; return Task.CompletedTask; };
|
||||
_middleware = new BasicAuthMiddleware(_next);
|
||||
|
||||
// Act
|
||||
await _middleware.InvokeAsync(ctx, _authMock.Object, _loggerMock.Object);
|
||||
|
||||
// Assert
|
||||
Assert.That(nextCalled, Is.True);
|
||||
Assert.That(ctx.Response.StatusCode, Is.EqualTo(StatusCodes.Status200OK));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user