using LehrerApp.Core.Models; using LehrerApp.Core.Services; using LehrerApp.Desktop.ViewModels.Exams; using Xunit; namespace LehrerApp.Desktop.Tests; /// Deckt 1.6 (Klausuren-Hauptseite) ab: Priorisierung end-to-end über die ViewModel-Schicht, /// Parallelkurs-Umschalter (1.6.4) und Genehmigung/Ankündigung (1.6.5). public sealed class ExamsOverviewViewModelTests { private static ExamsOverviewViewModel BuildVm(List groups, List exams, FakeMemberships? memberships = null, FakeResults? results = null) => new(new FakeExams(exams), results ?? new FakeResults(), new FakeGroups(groups), memberships ?? new FakeMemberships([]), new GradingService(), new SchoolYearService()); [Fact] public void Load_UnbearbeiteteKorrekturStehtVorGeplanterKlausur() { var group = new LearningGroup { Name = "Q1 Chemie", SchoolYear = new SchoolYearService().CurrentSchoolYear() }; var today = DateOnly.FromDateTime(DateTime.Today); var overdue = new Exam { GroupId = group.Id, Title = "Alte Klausur", Status = ExamStatus.Conducted, Date = today.AddDays(-10) }; var planned = new Exam { GroupId = group.Id, Title = "Neue Klausur", Status = ExamStatus.Planned, Date = today.AddDays(3) }; var vm = BuildVm([group], [overdue, planned]); vm.LoadCommand.Execute(null); Assert.Equal("Alte Klausur", vm.Rows[0].Title); Assert.Equal("Neue Klausur", vm.Rows[1].Title); } [Fact] public void Load_ParallelkurseWerdenAlsGeschwisterErkannt() { var groupA = new LearningGroup { Name = "Chemie GK Q1", SchoolYear = new SchoolYearService().CurrentSchoolYear() }; var groupB = new LearningGroup { Name = "Chemie GK Q1b", SchoolYear = groupA.SchoolYear }; var original = new Exam { GroupId = groupA.Id, Title = "Redox", Status = ExamStatus.Planned, Date = DateOnly.FromDateTime(DateTime.Today).AddDays(5) }; var duplicate = new Exam { GroupId = groupB.Id, Title = "Redox", Status = ExamStatus.Planned, Date = DateOnly.FromDateTime(DateTime.Today).AddDays(6), SharedExamGroupId = original.Id, }; var vm = BuildVm([groupA, groupB], [original, duplicate]); vm.LoadCommand.Execute(null); vm.SelectedRow = vm.Rows.Single(r => r.Exam.Id == original.Id); Assert.True(vm.SelectedRow.HasSibling); Assert.Single(vm.Siblings); Assert.Equal(duplicate.Id, vm.Siblings[0].Exam.Id); } [Fact] public void ToggleApproval_SetztUndLöschtDatum() { var group = new LearningGroup { Name = "Q1 Chemie", SchoolYear = new SchoolYearService().CurrentSchoolYear() }; var exam = new Exam { GroupId = group.Id, Title = "Klausur", Status = ExamStatus.Planned, Date = DateOnly.FromDateTime(DateTime.Today).AddDays(2) }; var vm = BuildVm([group], [exam]); vm.LoadCommand.Execute(null); vm.SelectedRow = vm.Rows[0]; vm.ToggleApprovalCommand.Execute(null); Assert.NotNull(exam.ApprovalGrantedAt); Assert.StartsWith("Genehmigt am", vm.ApprovalLabel); vm.ToggleApprovalCommand.Execute(null); Assert.Null(exam.ApprovalGrantedAt); Assert.Equal("Genehmigung noch ausstehend", vm.ApprovalLabel); } [Fact] public void Selection_ZeigtKorrekturfortschrittOderNotenspiegelJeNachStatus() { var group = new LearningGroup { Name = "Q1 Chemie", SchoolYear = new SchoolYearService().CurrentSchoolYear() }; var today = DateOnly.FromDateTime(DateTime.Today); var conducted = new Exam { GroupId = group.Id, Title = "Läuft", Status = ExamStatus.Conducted, Date = today.AddDays(-2) }; var returned = new Exam { GroupId = group.Id, Title = "Fertig", Status = ExamStatus.Returned, Date = today.AddDays(-20) }; var vm = BuildVm([group], [conducted, returned]); vm.LoadCommand.Execute(null); vm.SelectedRow = vm.Rows.Single(r => r.Exam.Id == conducted.Id); Assert.True(vm.ShowCorrectionProgress); Assert.False(vm.ShowGradeSummary); vm.SelectedRow = vm.Rows.Single(r => r.Exam.Id == returned.Id); Assert.False(vm.ShowCorrectionProgress); Assert.True(vm.ShowGradeSummary); } }