using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using GermanApp.Application.DTOs; using GermanApp.Application.Services; using GermanApp.Presentation.Controllers; using Microsoft.AspNetCore.Mvc; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace GermanApp.Tests.Integration.Controllers; /// /// Integration tests for LevelsController. /// Tests controller behavior with mocked services. /// [TestClass] public class LevelsControllerTests { private Mock? _mockLevelService; private LevelsController? _controller; [TestInitialize] public void TestInitialize() { _mockLevelService = new Mock(null!); _controller = new LevelsController(_mockLevelService.Object); } [TestCleanup] public void TestCleanup() { _controller = null; _mockLevelService = null; } // ==================== GET ALL LEVELS TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetAllLevels")] public async Task GetAllLevels_WithData_ReturnsOkWithLevels() { // Arrange var expectedLevels = new List { new LevelDto(1, "Beginner A1", "A1", 1), new LevelDto(2, "Elementary A2", "A2", 2) }; _mockLevelService!.Setup(s => s.GetAllLevelsAsync(It.IsAny())) .ReturnsAsync(expectedLevels); // Act var result = await _controller!.GetAllLevelsAsync(); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevels = okResult.Value as IReadOnlyList; Assert.IsNotNull(returnedLevels); Assert.AreEqual(2, returnedLevels.Count); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetAllLevels")] public async Task GetAllLevels_WithNoData_ReturnsEmptyList() { // Arrange var expectedLevels = new List(); _mockLevelService!.Setup(s => s.GetAllLevelsAsync(It.IsAny())) .ReturnsAsync(expectedLevels); // Act var result = await _controller!.GetAllLevelsAsync(); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevels = okResult.Value as IReadOnlyList; Assert.IsNotNull(returnedLevels); Assert.AreEqual(0, returnedLevels.Count); } // ==================== GET LEVEL BY ID TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetLevelById")] public async Task GetLevelById_WithExistingId_ReturnsOkWithLevel() { // Arrange var expectedLevel = new LevelDto(1, "Beginner A1", "A1", 1); _mockLevelService!.Setup(s => s.GetLevelByIdAsync(1, It.IsAny())) .ReturnsAsync(expectedLevel); // Act var result = await _controller!.GetLevelByIdAsync(1); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevel = okResult.Value as LevelDto; Assert.IsNotNull(returnedLevel); Assert.AreEqual(1, returnedLevel.Id); Assert.AreEqual("Beginner A1", returnedLevel.Name); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetLevelById")] public async Task GetLevelById_WithNonExistingId_ReturnsNotFound() { // Arrange _mockLevelService!.Setup(s => s.GetLevelByIdAsync(999, It.IsAny())) .ReturnsAsync((LevelDto?)null); // Act var result = await _controller!.GetLevelByIdAsync(999); // Assert Assert.IsInstanceOfType(result, typeof(NotFoundResult)); } // ==================== GET LEVEL BY CODE TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetLevelByCode")] public async Task GetLevelByCode_WithExistingCode_ReturnsOkWithLevel() { // Arrange var expectedLevel = new LevelDto(1, "Beginner A1", "A1", 1); _mockLevelService!.Setup(s => s.GetLevelByCodeAsync("A1", It.IsAny())) .ReturnsAsync(expectedLevel); // Act var result = await _controller!.GetLevelByCodeAsync("A1"); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevel = okResult.Value as LevelDto; Assert.IsNotNull(returnedLevel); Assert.AreEqual("A1", returnedLevel.Code); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetLevelByCode")] public async Task GetLevelByCode_WithNonExistingCode_ReturnsNotFound() { // Arrange _mockLevelService!.Setup(s => s.GetLevelByCodeAsync("INVALID", It.IsAny())) .ReturnsAsync((LevelDto?)null); // Act var result = await _controller!.GetLevelByCodeAsync("INVALID"); // Assert Assert.IsInstanceOfType(result, typeof(NotFoundResult)); } // ==================== CREATE LEVEL TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("CreateLevel")] public async Task CreateLevel_WithValidData_ReturnsCreatedAtAction() { // Arrange var createDto = new CreateLevelDto("Beginner A1", "A1", 1); var expectedLevel = new LevelDto(1, "Beginner A1", "A1", 1); _mockLevelService!.Setup(s => s.CreateLevelAsync(createDto, It.IsAny())) .ReturnsAsync(expectedLevel); // Act var result = await _controller!.CreateLevelAsync(createDto); // Assert Assert.IsInstanceOfType(result, typeof(CreatedAtActionResult)); var createdResult = result as CreatedAtActionResult; Assert.IsNotNull(createdResult); var returnedLevel = createdResult.Value as LevelDto; Assert.IsNotNull(returnedLevel); Assert.AreEqual(1, returnedLevel.Id); } // ==================== UPDATE LEVEL TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("UpdateLevel")] public async Task UpdateLevel_WithExistingId_ReturnsOkWithUpdatedLevel() { // Arrange var updateDto = new UpdateLevelDto("Updated A1", "A1", 1); var expectedLevel = new LevelDto(1, "Updated A1", "A1", 1); _mockLevelService!.Setup(s => s.UpdateLevelAsync(1, updateDto, It.IsAny())) .ReturnsAsync(expectedLevel); // Act var result = await _controller!.UpdateLevelAsync(1, updateDto); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevel = okResult.Value as LevelDto; Assert.IsNotNull(returnedLevel); Assert.AreEqual("Updated A1", returnedLevel.Name); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("UpdateLevel")] public async Task UpdateLevel_WithNonExistingId_ReturnsNotFound() { // Arrange var updateDto = new UpdateLevelDto("Updated A1", "A1", 1); _mockLevelService!.Setup(s => s.UpdateLevelAsync(999, updateDto, It.IsAny())) .ReturnsAsync((LevelDto?)null); // Act var result = await _controller!.UpdateLevelAsync(999, updateDto); // Assert Assert.IsInstanceOfType(result, typeof(NotFoundResult)); } // ==================== DELETE LEVEL TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("DeleteLevel")] public async Task DeleteLevel_WithExistingId_ReturnsNoContent() { // Arrange _mockLevelService!.Setup(s => s.DeleteLevelAsync(1, It.IsAny())) .ReturnsAsync(true); // Act var result = await _controller!.DeleteLevelAsync(1); // Assert Assert.IsInstanceOfType(result, typeof(NoContentResult)); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("DeleteLevel")] public async Task DeleteLevel_WithNonExistingId_ReturnsNotFound() { // Arrange _mockLevelService!.Setup(s => s.DeleteLevelAsync(999, It.IsAny())) .ReturnsAsync(false); // Act var result = await _controller!.DeleteLevelAsync(999); // Assert Assert.IsInstanceOfType(result, typeof(NotFoundResult)); } // ==================== GET FIRST LEVEL TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetFirstLevel")] public async Task GetFirstLevel_WithData_ReturnsOkWithLevel() { // Arrange var expectedLevel = new LevelDto(1, "Beginner A1", "A1", 1); _mockLevelService!.Setup(s => s.GetFirstLevelAsync(It.IsAny())) .ReturnsAsync(expectedLevel); // Act var result = await _controller!.GetFirstLevelAsync(); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevel = okResult.Value as LevelDto; Assert.IsNotNull(returnedLevel); Assert.AreEqual(1, returnedLevel.Order); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetFirstLevel")] public async Task GetFirstLevel_WithNoData_ReturnsNotFound() { // Arrange _mockLevelService!.Setup(s => s.GetFirstLevelAsync(It.IsAny())) .ReturnsAsync((LevelDto?)null); // Act var result = await _controller!.GetFirstLevelAsync(); // Assert Assert.IsInstanceOfType(result, typeof(NotFoundResult)); } // ==================== GET NEXT LEVEL TESTS ==================== [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetNextLevel")] public async Task GetNextLevel_WithExistingCurrentLevel_ReturnsOkWithNextLevel() { // Arrange var expectedLevel = new LevelDto(2, "Elementary A2", "A2", 2); _mockLevelService!.Setup(s => s.GetNextLevelAsync(1, It.IsAny())) .ReturnsAsync(expectedLevel); // Act var result = await _controller!.GetNextLevelAsync(1); // Assert Assert.IsInstanceOfType(result, typeof(OkObjectResult)); var okResult = result as OkObjectResult; Assert.IsNotNull(okResult); var returnedLevel = okResult.Value as LevelDto; Assert.IsNotNull(returnedLevel); Assert.AreEqual(2, returnedLevel.Order); } [TestMethod] [TestCategory("LevelsController")] [TestCategory("GetNextLevel")] public async Task GetNextLevel_WithNoNextLevel_ReturnsNotFound() { // Arrange _mockLevelService!.Setup(s => s.GetNextLevelAsync(5, It.IsAny())) .ReturnsAsync((LevelDto?)null); // Act var result = await _controller!.GetNextLevelAsync(5); // Assert Assert.IsInstanceOfType(result, typeof(NotFoundResult)); } }