using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging.Abstractions; using NSubstitute; using UniVerse.Application.DTOs.Notifications; using UniVerse.Application.Interfaces; using UniVerse.Domain.Entities; using UniVerse.Domain.Enums; using UniVerse.Domain.Exceptions; using UniVerse.Infrastructure.Data; using UniVerse.Infrastructure.Services; using Xunit; namespace UniVerse.Api.Tests.Auth; public class AuthServiceTests { [Fact] public async Task RefreshTokenAsync_InactiveUser_RevokesTokenAndThrowsForbidden() { await using var db = CreateDbContext(); db.Users.Add(new User { Id = 1, Email = "blocked@test.local", IsActive = false, Roles = [new UserRoleAssignment { UserId = 1, Role = UserRole.Student }] }); db.RefreshTokens.Add(new RefreshToken { Id = 1, UserId = 1, Token = "refresh-token", ExpiresAt = DateTime.UtcNow.AddDays(1), CreatedAt = DateTime.UtcNow }); await db.SaveChangesAsync(); var service = CreateService(db); await Assert.ThrowsAsync(() => service.RefreshTokenAsync("refresh-token")); var token = await db.RefreshTokens.SingleAsync(t => t.Token == "refresh-token"); Assert.NotNull(token.RevokedAt); } [Fact] public async Task GetCurrentUserAsync_InactiveUser_ThrowsForbidden() { await using var db = CreateDbContext(); db.Users.Add(new User { Id = 1, Email = "blocked@test.local", IsActive = false, Roles = [new UserRoleAssignment { UserId = 1, Role = UserRole.Student }] }); await db.SaveChangesAsync(); var service = CreateService(db); await Assert.ThrowsAsync(() => service.GetCurrentUserAsync(1)); } private static AppDbContext CreateDbContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase($"AuthServiceTests_{Guid.NewGuid()}") .Options; return new AppDbContext(options); } private static AuthService CreateService(AppDbContext db) { var config = new ConfigurationBuilder() .AddInMemoryCollection(new Dictionary { ["Jwt:Secret"] = "test-secret-test-secret-test-secret-test-secret", ["Jwt:Issuer"] = "UniVerse.Tests", ["Jwt:Audience"] = "UniVerse.Tests", ["Jwt:AccessTokenExpirationMinutes"] = "15", ["Jwt:RefreshTokenExpirationDays"] = "30" }) .Build(); var gamification = Substitute.For(); gamification.CalculateLevelAsync(Arg.Any()).Returns(1); var notifications = Substitute.For(); notifications.SendAsync(Arg.Any(), Arg.Any()) .Returns(Task.CompletedTask); return new AuthService(db, config, gamification, notifications, NullLogger.Instance); } }