using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging.Abstractions; using NSubstitute; using UniVerse.Application.DTOs.Notifications; using UniVerse.Application.Interfaces; using UniVerse.Domain.Entities; using UniVerse.Infrastructure.Data; using UniVerse.Infrastructure.Services; using Xunit; namespace UniVerse.Api.Tests.Users; public class UserServiceTests { [Fact] public async Task GetStatsAsync_ReturnsLevelProgressThresholds() { await using var db = CreateDbContext(); SeedLevelThresholds(db); db.Users.Add(new User { Id = 1, Email = "student@test.local", Xp = 120 }); await db.SaveChangesAsync(); var service = CreateService(db); var stats = await service.GetStatsAsync(1); Assert.Equal(2, stats.Level); Assert.Equal(100, stats.CurrentLevelXp); Assert.Equal(300, stats.NextLevelXp); } [Fact] public async Task GetStatsAsync_ReturnsNullNextLevelAtMaxConfiguredLevel() { await using var db = CreateDbContext(); SeedLevelThresholds(db); db.Users.Add(new User { Id = 1, Email = "student@test.local", Xp = 350 }); await db.SaveChangesAsync(); var service = CreateService(db); var stats = await service.GetStatsAsync(1); Assert.Equal(3, stats.Level); Assert.Equal(300, stats.CurrentLevelXp); Assert.Null(stats.NextLevelXp); } private static AppDbContext CreateDbContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase($"UserServiceTests_{Guid.NewGuid()}") .Options; return new AppDbContext(options); } private static UserService CreateService(AppDbContext db) { var notifications = Substitute.For(); notifications.CreateUserNotificationAsync( Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any()) .Returns(callInfo => new UserNotificationDto(1, callInfo.ArgAt(1), callInfo.ArgAt(2), callInfo.ArgAt(3), false, DateTime.UtcNow)); notifications.SendAsync(Arg.Any(), Arg.Any()) .Returns(Task.CompletedTask); var gamification = new GamificationService(db, notifications, NullLogger.Instance); return new UserService(db, gamification); } private static void SeedLevelThresholds(AppDbContext db) { db.LevelThresholds.AddRange( new LevelThreshold { Level = 1, RequiredXp = 0 }, new LevelThreshold { Level = 2, RequiredXp = 100 }, new LevelThreshold { Level = 3, RequiredXp = 300 }); db.SaveChanges(); } }