using LehrerApp.Desktop.Services; using LehrerApp.Desktop.ViewModels.ClassTeacher; using Xunit; namespace LehrerApp.Desktop.Tests; public sealed class ClassTeacherViewModelsTests { [Fact] public void GroupByStudentAndDay_FasstFehlstundenProSchuelerUndTagZusammen() { var entries = new[] { new UntisClassAbsenceEntryDto("Muster Max", 1, "6a", 20260824, 1, 45, "HED", "Che", "Absent", "Krank", 1, "24.08.26", true, null, 3, "nicht entsch.", false), new UntisClassAbsenceEntryDto("Muster Max", 1, "6a", 20260824, 1, 45, "PAN", "Kunst", null, "Krank", 2, "24.08.26", true, null, 5, "nicht entsch.", true), new UntisClassAbsenceEntryDto("Andere Schuelerin", 2, "6a", 20260824, 1, 20, "BEN", "Deu", "Verspätung", null, 3, "24.08.26", false, "Zug verpasst", 1, "entsch.", false), }; var rows = ClassAbsenceDaySummaryRow.GroupByStudentAndDay(entries); Assert.Equal(2, rows.Count); var max = rows[1]; Assert.Equal("Muster Max", max.StudentName); Assert.Equal(2, max.TotalAbsentPeriods); Assert.Equal(90, max.TotalAbsentMinutes); Assert.Equal(["Che", "Kunst"], max.Subjects); Assert.Equal([3, 5], max.PeriodNumbers.Order()); Assert.Equal(["nicht entsch."], max.Statuses); Assert.Equal(["Absent"], max.AbsenceReasons); Assert.Equal("Krank", max.Note); Assert.Null(max.ExcuseNote); Assert.True(max.CountsAsFullDay); var andere = rows[0]; Assert.Equal("Andere Schuelerin", andere.StudentName); Assert.Equal(1, andere.TotalAbsentPeriods); Assert.Equal(20, andere.TotalAbsentMinutes); Assert.Equal(["Deu"], andere.Subjects); Assert.Null(andere.Note); Assert.Equal("Zug verpasst", andere.ExcuseNote); Assert.False(andere.CountsAsFullDay); } [Fact] public void GroupByStudentAndDay_TrenntGleichenNamenAnUnterschiedlichenTagen() { var entries = new[] { new UntisClassAbsenceEntryDto("Muster Max", 1, "6a", 20260824, 1, 45, "HED", "Che", null, null, 1, "24.08.26", true, null, 3, "nicht entsch.", false), new UntisClassAbsenceEntryDto("Muster Max", 1, "6a", 20260825, 1, 45, "HED", "Che", null, null, 2, "25.08.26", true, null, 3, "nicht entsch.", false), }; var rows = ClassAbsenceDaySummaryRow.GroupByStudentAndDay(entries); Assert.Equal(2, rows.Count); Assert.Equal(new DateOnly(2026, 8, 25), rows[0].Date); Assert.Equal(new DateOnly(2026, 8, 24), rows[1].Date); } [Fact] public void RosterBuild_OrdnetFehlzeitPerExternKeyUndKlassenbuchPerNameZu() { var students = new[] { Student(1001, "Ada Müller"), Student(1002, "Ben Schmidt"), Student(1003, "Cem Yilmaz"), }; var todayAbsences = new[] { new ClassAbsenceDaySummaryRow(new DateOnly(2026, 8, 25), "Ada Müller", 1001, 2, 90, ["Che"], [3, 4], ["nicht entsch."], ["Absent"], null, null, false), }; var recentClassRegister = new[] { new UntisForeignClassRegisterEventDto("6a", 20260824, "Deu", "Ben Schmidt", "mueller", "Vergessen", "Organisation", "Buch vergessen"), }; var roster = ClassTeacherRosterRow.Build(students, todayAbsences, recentClassRegister); Assert.Equal(3, roster.Count); var ada = Assert.Single(roster, r => r.StudentName == "Ada Müller"); Assert.True(ada.HasAbsenceToday); Assert.Contains("nicht entsch.", ada.AbsenceTooltip); Assert.False(ada.HasRecentClassRegisterEntry); var ben = Assert.Single(roster, r => r.StudentName == "Ben Schmidt"); Assert.False(ben.HasAbsenceToday); Assert.True(ben.HasRecentClassRegisterEntry); var cem = Assert.Single(roster, r => r.StudentName == "Cem Yilmaz"); Assert.False(cem.HasAbsenceToday); Assert.False(cem.HasRecentClassRegisterEntry); } private static UntisStudentDto Student(int externKey, string displayName) => new( UntisId: externKey, ExternKey: externKey, ClassName: "6a", Name: displayName, LongName: null, ForeName: null, DisplayName: displayName, Gender: null, BirthDate: null, BirthDateRaw: null, EntryDate: null, EntryDateRaw: null, ExitDate: null, ExitDateRaw: null, Text: null, MedicalReportDuty: null, Schulpflicht: null, Majority: null, Address: new UntisStudentAddressDto(null, null, null, null, null, null), AttributeIL: null); }