126 lines
4.1 KiB
C#
126 lines
4.1 KiB
C#
namespace Domain.Tests.Services;
|
|
|
|
using Domain.Entities;
|
|
using Domain.Exceptions;
|
|
using Domain.Services;
|
|
using Domain.ValueObjects;
|
|
using FluentAssertions;
|
|
using Xunit;
|
|
|
|
public class EnrollmentDomainServiceTests
|
|
{
|
|
private readonly EnrollmentDomainService _sut = new();
|
|
private static Email ValidEmail => Email.Create("test@example.com");
|
|
|
|
[Fact]
|
|
public void ValidateEnrollment_WhenValid_ShouldNotThrow()
|
|
{
|
|
var student = new Student("John Doe", ValidEmail);
|
|
var subject = new Subject("Math", professorId: 1);
|
|
|
|
var act = () => _sut.ValidateEnrollment(student, subject);
|
|
|
|
act.Should().NotThrow();
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateEnrollment_WhenMaxEnrollmentsReached_ShouldThrow()
|
|
{
|
|
var student = new Student("John Doe", ValidEmail);
|
|
AddEnrollmentsWithDifferentProfessors(student, 3);
|
|
var subject = new Subject("Physics", professorId: 99);
|
|
|
|
var act = () => _sut.ValidateEnrollment(student, subject);
|
|
|
|
act.Should().Throw<MaxEnrollmentsExceededException>()
|
|
.Which.Code.Should().Be("MAX_ENROLLMENTS");
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateEnrollment_WhenSameProfessor_ShouldThrow()
|
|
{
|
|
var student = new Student("John Doe", ValidEmail);
|
|
var existingSubject = new Subject("Math", professorId: 1);
|
|
AddEnrollmentWithSubject(student, existingSubject);
|
|
|
|
var newSubject = new Subject("Algebra", professorId: 1);
|
|
|
|
var act = () => _sut.ValidateEnrollment(student, newSubject);
|
|
|
|
act.Should().Throw<SameProfessorConstraintException>()
|
|
.Which.Code.Should().Be("SAME_PROFESSOR");
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateEnrollment_WhenDuplicateSubject_ShouldThrow()
|
|
{
|
|
var student = new Student("John Doe", ValidEmail);
|
|
var subject = new Subject("Math", professorId: 1);
|
|
SetSubjectId(subject, 10);
|
|
AddEnrollmentWithSubject(student, subject);
|
|
|
|
// Same subject ID but different professor to bypass professor check
|
|
var duplicateSubject = new Subject("Math", professorId: 2);
|
|
SetSubjectId(duplicateSubject, 10);
|
|
|
|
var act = () => _sut.ValidateEnrollment(student, duplicateSubject);
|
|
|
|
act.Should().Throw<DuplicateEnrollmentException>()
|
|
.Which.Code.Should().Be("DUPLICATE_ENROLLMENT");
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEnrollment_WhenValid_ShouldCreateAndAddToStudent()
|
|
{
|
|
var student = new Student("John Doe", ValidEmail);
|
|
var subject = new Subject("Math", professorId: 1);
|
|
|
|
var enrollment = _sut.CreateEnrollment(student, subject);
|
|
|
|
enrollment.Should().NotBeNull();
|
|
student.Enrollments.Should().Contain(enrollment);
|
|
enrollment.StudentId.Should().Be(student.Id);
|
|
enrollment.SubjectId.Should().Be(subject.Id);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEnrollment_WhenInvalid_ShouldNotAddToStudent()
|
|
{
|
|
var student = new Student("John Doe", ValidEmail);
|
|
AddEnrollmentsWithDifferentProfessors(student, 3);
|
|
var subject = new Subject("Physics", professorId: 99);
|
|
|
|
var act = () => _sut.CreateEnrollment(student, subject);
|
|
|
|
act.Should().Throw<MaxEnrollmentsExceededException>();
|
|
student.Enrollments.Should().HaveCount(3);
|
|
}
|
|
|
|
private static void AddEnrollmentsWithDifferentProfessors(Student student, int count)
|
|
{
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var subject = new Subject($"Subject{i}", professorId: i + 1);
|
|
SetSubjectId(subject, i + 1);
|
|
AddEnrollmentWithSubject(student, subject);
|
|
}
|
|
}
|
|
|
|
private static void AddEnrollmentWithSubject(Student student, Subject subject)
|
|
{
|
|
var enrollment = new Enrollment(student.Id, subject.Id);
|
|
SetSubjectOnEnrollment(enrollment, subject);
|
|
student.AddEnrollment(enrollment);
|
|
}
|
|
|
|
private static void SetSubjectOnEnrollment(Enrollment enrollment, Subject subject)
|
|
{
|
|
typeof(Enrollment).GetProperty("Subject")!.SetValue(enrollment, subject);
|
|
}
|
|
|
|
private static void SetSubjectId(Subject subject, int id)
|
|
{
|
|
typeof(Subject).GetProperty("Id")!.SetValue(subject, id);
|
|
}
|
|
}
|