using Core.Entities; using Core.Models; using Core.YearTransition; using NUnit.Framework; using Tests.Builders; namespace Tests.YearTransition; [TestFixture] public class GraduatingGradeResolver_Tests { [Test] public void FromSchoolLevel_MiddleSchool_Returns8() { Assert.That(GraduatingGradeResolver.FromSchoolLevel(SchoolLevel.MiddleSchool), Is.EqualTo(8)); } [Test] public void FromSchoolLevel_HighSchool_Returns12() { Assert.That(GraduatingGradeResolver.FromSchoolLevel(SchoolLevel.HighSchool), Is.EqualTo(12)); } [Test] public void FromSchoolLevel_Null_ReturnsNull() { Assert.That(GraduatingGradeResolver.FromSchoolLevel(null), Is.Null); } } [TestFixture] public class YearTransitionPlanner_Tests { [SetUp] public void SetUp() { StudentBuilder.ResetIdCounter(); } [Test] public void SuggestReturning_BelowGraduatingGrade_IsTrue() { var student = StudentBuilder.Create("Ann", "Lee").WithGrade(7).Build(); Assert.That(YearTransitionPlanner.SuggestReturning(student, graduatingGrade: 8), Is.True); } [Test] public void SuggestReturning_AtGraduatingGrade_IsFalse() { var student = StudentBuilder.Create("Ann", "Lee").WithGrade(8).Build(); Assert.That(YearTransitionPlanner.SuggestReturning(student, graduatingGrade: 8), Is.False); } [Test] public void Build_PromotesReturningStudents_MiddleSchool() { var returning = StudentBuilder.Create("Ann", "Lee").WithGrade(6).WithTsaYear(1).Build(); var graduating = StudentBuilder.Create("Bob", "Smith").WithGrade(8).WithTsaYear(3).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [returning, graduating], ReturningStudentIds = new HashSet { returning.Id }, GraduatingGrade = 8, TargetCompetitionYear = "2027" }); Assert.That(plan.ReturningCount, Is.EqualTo(1)); Assert.That(plan.RemovalCount, Is.EqualTo(1)); Assert.That(plan.Promotions[0].NewGrade, Is.EqualTo(7)); Assert.That(plan.Promotions[0].NewTsaYear, Is.EqualTo(2)); Assert.That(plan.StudentsToRemove[0].Id, Is.EqualTo(graduating.Id)); } [Test] public void Build_CapsGradeAtGraduatingGrade_HighSchool() { var senior = StudentBuilder.Create("Chris", "Young").WithGrade(12).WithTsaYear(4).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [senior], ReturningStudentIds = new HashSet { senior.Id }, GraduatingGrade = 12, TargetCompetitionYear = "2027" }); Assert.That(plan.Promotions[0].NewGrade, Is.EqualTo(12)); Assert.That(plan.Promotions[0].NewTsaYear, Is.EqualTo(5)); Assert.That(plan.Warnings, Has.Some.Contain("graduating grade")); } [Test] public void Build_CapsGradeAtEight_WhenMiddleSchoolReturnerAtGraduatingGrade() { var eighth = StudentBuilder.Create("Dana", "Nguyen").WithGrade(8).WithTsaYear(2).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [eighth], ReturningStudentIds = new HashSet { eighth.Id }, GraduatingGrade = 8, TargetCompetitionYear = "2027" }); Assert.That(plan.Promotions[0].NewGrade, Is.EqualTo(8)); Assert.That(plan.Warnings, Has.Some.Contain("graduating grade")); } [Test] public void Build_AssignsOfficersAndClearsOthers() { var president = StudentBuilder.Create("Eve", "Adams").WithGrade(7).AsPresident().Build(); var vp = StudentBuilder.Create("Frank", "Baker").WithGrade(6).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [president, vp], ReturningStudentIds = new HashSet { president.Id, vp.Id }, GraduatingGrade = 8, TargetCompetitionYear = "2027", OfficerAssignments = new Dictionary { [OfficerRole.President] = vp.Id, [OfficerRole.VicePresident] = president.Id } }); var eve = plan.Promotions.Single(p => p.Student.Id == president.Id); var frank = plan.Promotions.Single(p => p.Student.Id == vp.Id); Assert.That(eve.PreviousOfficerRole, Is.EqualTo(OfficerRole.President)); Assert.That(eve.NewOfficerRole, Is.EqualTo(OfficerRole.VicePresident)); Assert.That(frank.NewOfficerRole, Is.EqualTo(OfficerRole.President)); var presidentChange = plan.OfficerChanges.Single(c => c.Role == OfficerRole.President); Assert.That(presidentChange.PreviousOfficer!.Id, Is.EqualTo(president.Id)); Assert.That(presidentChange.NewOfficer!.Id, Is.EqualTo(vp.Id)); } [Test] public void Build_WarnsWhenOfficerAssignedToNonReturningStudent() { var returning = StudentBuilder.Create("Gina", "Cole").WithGrade(6).Build(); var leaving = StudentBuilder.Create("Hank", "Diaz").WithGrade(8).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [returning, leaving], ReturningStudentIds = new HashSet { returning.Id }, GraduatingGrade = 8, TargetCompetitionYear = "2027", OfficerAssignments = new Dictionary { [OfficerRole.President] = leaving.Id } }); Assert.That(plan.Warnings, Has.Some.Contain("not marked returning")); Assert.That(plan.Promotions[0].NewOfficerRole, Is.Null); } [Test] public void Build_WarnsWhenSameStudentHasTwoOffices() { var student = StudentBuilder.Create("Ivy", "Evans").WithGrade(7).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [student], ReturningStudentIds = new HashSet { student.Id }, GraduatingGrade = 8, TargetCompetitionYear = "2027", OfficerAssignments = new Dictionary { [OfficerRole.President] = student.Id, [OfficerRole.Treasurer] = student.Id } }); Assert.That(plan.Warnings, Has.Some.Contain("more than one officer role")); Assert.That(plan.Promotions[0].NewOfficerRole, Is.Null); } [Test] public void MatchPastedNames_MatchesLastCommaFirstAndFirstLast() { var a = StudentBuilder.Create("Ann", "Lee").WithGrade(6).Build(); var b = StudentBuilder.Create("Bob", "Smith").WithGrade(7).Build(); var result = YearTransitionPlanner.MatchPastedNames( [a, b], ["Lee, Ann", "Bob Smith", "Nobody Here"]); Assert.That(result.MatchedStudentIds, Is.EquivalentTo(new[] { a.Id, b.Id })); Assert.That(result.UnmatchedNames, Is.EquivalentTo(new[] { "Nobody Here" })); } [Test] public void MatchPastedNames_AmbiguousWhenDuplicateNames() { var a = StudentBuilder.Create("Ann", "Lee").WithGrade(6).Build(); var b = StudentBuilder.Create("Ann", "Lee").WithGrade(7).Build(); var result = YearTransitionPlanner.MatchPastedNames([a, b], ["Ann Lee"]); Assert.That(result.AmbiguousNames, Is.EquivalentTo(new[] { "Ann Lee" })); Assert.That(result.MatchedStudentIds, Is.EquivalentTo(new[] { a.Id, b.Id })); } [Test] public void Build_IncludesUnmatchedAndAmbiguousFromPaste() { var a = StudentBuilder.Create("Ann", "Lee").WithGrade(6).Build(); var b = StudentBuilder.Create("Ann", "Lee").WithGrade(7).Build(); var plan = YearTransitionPlanner.Build(new YearTransitionRequest { Students = [a, b], ReturningStudentIds = new HashSet { a.Id }, GraduatingGrade = 8, TargetCompetitionYear = "2027", PastedNames = ["Ann Lee", "Zed Zulu"] }); Assert.That(plan.AmbiguousPastedNames, Has.Member("Ann Lee")); Assert.That(plan.UnmatchedPastedNames, Has.Member("Zed Zulu")); Assert.That(plan.Warnings, Has.Some.Contain("matched more than one")); } }