using System; using System.Threading; using System.Threading.Tasks; using GermanApp.Application.DTOs; using GermanApp.Application.Services; using GermanApp.Domain.Entities; using GermanApp.Domain.Interfaces; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace GermanApp.Tests.Unit.Application.Services; [TestClass] public class ProgressServiceTests { private Mock _mockProgressRepo; private Mock _mockLessonRepo; private Mock _mockLevelRepo; private ProgressService _service; [TestInitialize] public void Setup() { _mockProgressRepo = new Mock(); _mockLessonRepo = new Mock(); _mockLevelRepo = new Mock(); _service = new ProgressService( _mockProgressRepo.Object, _mockLessonRepo.Object, _mockLevelRepo.Object); } [TestMethod] public async Task GetUserProgressAsync_WithExistingProgress_ReturnsDto() { var progress = UserProgress.Create(1, 1); progress.MarkAsCompleted(85); _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 1, It.IsAny())) .ReturnsAsync(progress); var result = await _service.GetUserProgressAsync(1, 1); Assert.IsNotNull(result); Assert.IsTrue(result.IsCompleted); Assert.AreEqual(85, result.QuizScore); } [TestMethod] public async Task GetUserProgressAsync_WithNoProgress_ReturnsNull() { _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 999, It.IsAny())) .ReturnsAsync((UserProgress?)null); var result = await _service.GetUserProgressAsync(1, 999); Assert.IsNull(result); } [TestMethod] public async Task HasUserCompletedLessonAsync_ReturnsRepositoryResult() { _mockProgressRepo.Setup(r => r.HasUserCompletedLessonAsync(1, 1, It.IsAny())) .ReturnsAsync(true); var result = await _service.HasUserCompletedLessonAsync(1, 1); Assert.IsTrue(result); } [TestMethod] public async Task MarkLessonAsCompletedAsync_WithNewProgress_CreatesProgress() { _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 1, It.IsAny())) .ReturnsAsync((UserProgress?)null); var newProgress = UserProgress.Create(1, 1); newProgress.MarkAsCompleted(90); _mockProgressRepo.Setup(r => r.AddAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(newProgress); var result = await _service.MarkLessonAsCompletedAsync(1, 1, 90); Assert.IsNotNull(result); Assert.IsTrue(result.IsCompleted); Assert.AreEqual(90, result.QuizScore); } [TestMethod] public async Task MarkLessonAsCompletedAsync_WithExistingProgress_UpdatesProgress() { var existingProgress = UserProgress.Create(1, 1); existingProgress.UpdateQuizScore(50); _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 1, It.IsAny())) .ReturnsAsync(existingProgress); _mockProgressRepo.Setup(r => r.UpdateAsync(existingProgress, It.IsAny())) .Returns(Task.CompletedTask); var result = await _service.MarkLessonAsCompletedAsync(1, 1, 85); Assert.IsNotNull(result); Assert.IsTrue(result.IsCompleted); } [TestMethod] public async Task UpdateUserProgressAsync_WithNewProgress_CreatesProgress() { var dto = new UpdateUserProgressDto(1, false, 60); _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 1, It.IsAny())) .ReturnsAsync((UserProgress?)null); var newProgress = UserProgress.Create(1, 1); newProgress.UpdateQuizScore(60); _mockProgressRepo.Setup(r => r.AddAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(newProgress); var result = await _service.UpdateUserProgressAsync(1, dto); Assert.IsNotNull(result); Assert.AreEqual(60, result.QuizScore); } [TestMethod] public async Task ResetLessonProgressAsync_WithExistingProgress_ReturnsTrue() { var progress = UserProgress.Create(1, 1); progress.MarkAsCompleted(90); _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 1, It.IsAny())) .ReturnsAsync(progress); _mockProgressRepo.Setup(r => r.UpdateAsync(progress, It.IsAny())) .Returns(Task.CompletedTask); var result = await _service.ResetLessonProgressAsync(1, 1); Assert.IsTrue(result); } [TestMethod] public async Task ResetLessonProgressAsync_WithNoProgress_ReturnsFalse() { _mockProgressRepo.Setup(r => r.GetByUserAndLessonAsync(1, 999, It.IsAny())) .ReturnsAsync((UserProgress?)null); var result = await _service.ResetLessonProgressAsync(1, 999); Assert.IsFalse(result); } [TestMethod] public async Task GetAverageScoreForLevelAsync_ReturnsRepositoryResult() { _mockProgressRepo.Setup(r => r.GetAverageScoreForLevelAsync(1, 1, It.IsAny())) .ReturnsAsync(75.5); var result = await _service.GetAverageScoreForLevelAsync(1, 1); Assert.AreEqual(75.5, result); } [TestMethod] public async Task GetLevelCompletionPercentageAsync_ReturnsRepositoryResult() { _mockProgressRepo.Setup(r => r.GetLevelCompletionPercentageAsync(1, 1, It.IsAny())) .ReturnsAsync(60.0); var result = await _service.GetLevelCompletionPercentageAsync(1, 1); Assert.AreEqual(60.0, result); } }