namespace Application.Tests.Enrollments; using Application.Enrollments.Commands; using Domain.Entities; using Domain.Exceptions; using Domain.Ports.Repositories; using Domain.ValueObjects; using FluentAssertions; using NSubstitute; using Xunit; public class UnenrollStudentCommandTests { private readonly IEnrollmentRepository _enrollmentRepository; private readonly IStudentRepository _studentRepository; private readonly IUnitOfWork _unitOfWork; private readonly UnenrollStudentHandler _handler; public UnenrollStudentCommandTests() { _enrollmentRepository = Substitute.For(); _studentRepository = Substitute.For(); _unitOfWork = Substitute.For(); _handler = new UnenrollStudentHandler(_enrollmentRepository, _studentRepository, _unitOfWork); } [Fact] public async Task Handle_WhenEnrollmentExists_ShouldUnenrollStudent() { // Arrange var enrollment = new Enrollment(1, 1); SetEntityId(enrollment, 1); var student = new Student("John Doe", Email.Create("john@example.com")); SetEntityId(student, 1); student.AddEnrollment(enrollment); _enrollmentRepository.GetByIdAsync(1, Arg.Any()) .Returns(enrollment); _studentRepository.GetByIdWithEnrollmentsAsync(1, Arg.Any()) .Returns(student); var command = new UnenrollStudentCommand(1); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.Should().BeTrue(); _enrollmentRepository.Received(1).Delete(enrollment); await _unitOfWork.Received(1).SaveChangesAsync(Arg.Any()); } [Fact] public async Task Handle_WhenEnrollmentNotFound_ShouldThrow() { // Arrange _enrollmentRepository.GetByIdAsync(999, Arg.Any()) .Returns((Enrollment?)null); var command = new UnenrollStudentCommand(999); // Act var act = () => _handler.Handle(command, CancellationToken.None); // Assert await act.Should().ThrowAsync(); } [Fact] public async Task Handle_WhenStudentNotFound_ShouldStillDeleteEnrollment() { // Arrange var enrollment = new Enrollment(999, 1); SetEntityId(enrollment, 1); _enrollmentRepository.GetByIdAsync(1, Arg.Any()) .Returns(enrollment); _studentRepository.GetByIdWithEnrollmentsAsync(999, Arg.Any()) .Returns((Student?)null); var command = new UnenrollStudentCommand(1); // Act var result = await _handler.Handle(command, CancellationToken.None); // Assert result.Should().BeTrue(); _enrollmentRepository.Received(1).Delete(enrollment); } private static void SetEntityId(T entity, int id) where T : class { typeof(T).GetProperty("Id")?.SetValue(entity, id); } }