using System.IdentityModel.Tokens.Jwt; using MicCheck.Api.Common.Security.Authorization; using MicCheck.Api.Organizations; using MicCheck.Api.Users; using Microsoft.Extensions.Configuration; using NUnit.Framework; namespace MicCheck.Api.Tests.Unit.Authorization; [TestFixture] public class TokenServiceTests { private IConfiguration _configuration = null!; private TokenService _tokenService = null!; [SetUp] public void SetUp() { _configuration = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["Jwt:SecretKey"] = "test-secret-key-that-is-long-enough-32c", ["Jwt:Issuer"] = "MicCheck", ["Jwt:Audience"] = "MicCheck", ["Jwt:ExpiryMinutes"] = "60", }) .Build(); _tokenService = new TokenService(_configuration); } private static User BuildUser(int id = 1, string email = "alice@example.com") => new() { Email = email, FirstName = "Alice", LastName = "Smith", PasswordHash = "hashed", IsActive = true, CreatedAt = DateTimeOffset.UtcNow }; [Test] public void WhenAUserIsProvided_ThenATokenIsReturned() { var result = _tokenService.GenerateToken(BuildUser()); Assert.That(result.Token, Is.Not.Null.And.Not.Empty); } [Test] public void WhenATokenIsGenerated_ThenItContainsTheUserEmailClaim() { var user = BuildUser(email: "bob@example.com"); var result = _tokenService.GenerateToken(user); var handler = new JwtSecurityTokenHandler(); var jwt = handler.ReadJwtToken(result.Token); Assert.That(jwt.Claims.Any(c => c.Type == JwtRegisteredClaimNames.Email && c.Value == "bob@example.com"), Is.True); } [Test] public void WhenATokenIsGenerated_ThenItHasAFutureExpiry() { var result = _tokenService.GenerateToken(BuildUser()); Assert.That(result.ExpiresAt, Is.GreaterThan(DateTime.UtcNow)); } [Test] public void WhenATokenIsGenerated_ThenItHasTheConfiguredIssuer() { var result = _tokenService.GenerateToken(BuildUser()); var handler = new JwtSecurityTokenHandler(); var jwt = handler.ReadJwtToken(result.Token); Assert.That(jwt.Issuer, Is.EqualTo("MicCheck")); } [Test] public void WhenUserBelongsToOrganizations_ThenTokenContainsOrganizationClaims() { var user = BuildUser(); user.Organizations.Add(new OrganizationUser { OrganizationId = 42, UserId = user.Id, Role = OrganizationRole.Admin }); var result = _tokenService.GenerateToken(user); var handler = new JwtSecurityTokenHandler(); var jwt = handler.ReadJwtToken(result.Token); Assert.That(jwt.Claims.Any(c => c.Type == "OrganizationId" && c.Value == "42"), Is.True); Assert.That(jwt.Claims.Any(c => c.Type == "OrganizationRole" && c.Value == "Admin"), Is.True); } }