HaniBlindBox/server/HoneyBox/tests/HoneyBox.Tests/Services/JwtServiceTests.cs
2026-01-04 01:47:02 +08:00

208 lines
5.5 KiB
C#

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using FsCheck;
using FsCheck.Xunit;
using HoneyBox.Core.Services;
using HoneyBox.Model.Entities;
using HoneyBox.Model.Models.Auth;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;
namespace HoneyBox.Tests.Services;
public class JwtServiceTests
{
private readonly JwtSettings _jwtSettings;
private readonly Mock<ILogger<JwtService>> _mockLogger;
private readonly JwtService _jwtService;
public JwtServiceTests()
{
_jwtSettings = new JwtSettings
{
Secret = "your-secret-key-must-be-at-least-32-characters-long-for-hs256",
Issuer = "HoneyBox",
Audience = "HoneyBoxUsers",
ExpirationMinutes = 1440,
RefreshTokenExpirationDays = 7
};
_mockLogger = new Mock<ILogger<JwtService>>();
_jwtService = new JwtService(_jwtSettings, _mockLogger.Object);
}
[Fact]
public void GenerateToken_WithValidUser_ReturnsValidToken()
{
// Arrange
var user = new User
{
Id = 1,
Nickname = "TestUser",
Uid = "uid123",
OpenId = "openid123",
HeadImg = "https://example.com/avatar.jpg",
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
// Act
var token = _jwtService.GenerateToken(user);
// Assert
Assert.NotNull(token);
Assert.NotEmpty(token);
// Verify token can be read
var handler = new JwtSecurityTokenHandler();
var jwtToken = handler.ReadJwtToken(token);
Assert.NotNull(jwtToken);
Assert.Equal(_jwtSettings.Issuer, jwtToken.Issuer);
Assert.Equal(_jwtSettings.Audience, jwtToken.Audiences.First());
}
[Fact]
public void GenerateToken_WithNullUser_ThrowsArgumentNullException()
{
// Act & Assert
Assert.Throws<ArgumentNullException>(() => _jwtService.GenerateToken(null!));
}
[Fact]
public void ValidateToken_WithValidToken_ReturnsClaimsPrincipal()
{
// Arrange
var user = new User
{
Id = 1,
Nickname = "TestUser",
Uid = "uid123",
OpenId = "openid123",
HeadImg = "https://example.com/avatar.jpg",
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
var token = _jwtService.GenerateToken(user);
// Act
var principal = _jwtService.ValidateToken(token);
// Assert
Assert.NotNull(principal);
var userIdClaim = principal.FindFirst(ClaimTypes.NameIdentifier);
Assert.NotNull(userIdClaim);
Assert.Equal("1", userIdClaim.Value);
}
[Fact]
public void ValidateToken_WithInvalidToken_ReturnsNull()
{
// Act
var principal = _jwtService.ValidateToken("invalid.token.here");
// Assert
Assert.Null(principal);
}
[Fact]
public void ValidateToken_WithNullToken_ReturnsNull()
{
// Act
var principal = _jwtService.ValidateToken(null!);
// Assert
Assert.Null(principal);
}
[Fact]
public void ValidateToken_WithEmptyToken_ReturnsNull()
{
// Act
var principal = _jwtService.ValidateToken(string.Empty);
// Assert
Assert.Null(principal);
}
[Fact]
public void GetUserIdFromToken_WithValidToken_ReturnsCorrectUserId()
{
// Arrange
var user = new User
{
Id = 42,
Nickname = "TestUser",
Uid = "uid123",
OpenId = "openid123",
HeadImg = "https://example.com/avatar.jpg",
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
var token = _jwtService.GenerateToken(user);
// Act
var userId = _jwtService.GetUserIdFromToken(token);
// Assert
Assert.NotNull(userId);
Assert.Equal(42, userId);
}
[Fact]
public void GetUserIdFromToken_WithInvalidToken_ReturnsNull()
{
// Act
var userId = _jwtService.GetUserIdFromToken("invalid.token.here");
// Assert
Assert.Null(userId);
}
[Fact]
public void GetUserIdFromToken_WithNullToken_ReturnsNull()
{
// Act
var userId = _jwtService.GetUserIdFromToken(null!);
// Assert
Assert.Null(userId);
}
[Fact]
public void GetUserIdFromToken_WithEmptyToken_ReturnsNull()
{
// Act
var userId = _jwtService.GetUserIdFromToken(string.Empty);
// Assert
Assert.Null(userId);
}
/// <summary>
/// Property 3: 登录成功Token生成
/// For any valid user, generating a token should produce a valid JWT that contains the user's ID
/// and can be validated to extract the same user ID.
/// Validates: Requirements 3.1, 3.2
/// </summary>
[Property(MaxTest = 100)]
public bool GeneratedTokenContainsCorrectUserId(PositiveInt userId, NonEmptyString nickname)
{
var user = new User
{
Id = userId.Item,
Nickname = nickname.Item,
Uid = $"uid{userId.Item}",
OpenId = $"openid{userId.Item}",
HeadImg = "https://example.com/avatar.jpg",
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
var token = _jwtService.GenerateToken(user);
var extractedUserId = _jwtService.GetUserIdFromToken(token);
return extractedUserId == userId.Item;
}
}