using LehrerApp.Core.Models; using LehrerApp.Desktop.ViewModels.Groups; using Xunit; namespace LehrerApp.Desktop.Tests; public sealed class SeatingQuickCheckTests { private static (SeatingPlanTabViewModel Vm, FakeEntries Entries, ParticipationSession Session, Student Student) Build(bool readOnly = false) { var group = Guid.NewGuid(); var student = new Student { FirstName = "Anna", LastName = "Beispiel" }; var session = new ParticipationSession { GroupId = group, Date = DateOnly.FromDateTime(DateTime.Today) }; var entries = new FakeEntries(); var plan = new SeatingPlan { GroupId = group, Rows = 1, Columns = 2, Assignments = [new SeatAssignment { Row = 0, Column = 0, StudentId = student.Id }] }; var vm = new SeatingPlanTabViewModel(new FakeSeatingPlans([plan]), new FakeStudents([student]), new FakeMemberships([new GroupMembership { GroupId = group, StudentId = student.Id }]), new FakeSessions([session]), entries, new FakeAspects()); vm.Initialize(group, readOnly); return (vm, entries, session, student); } [Fact] public void Attendance_UsesSeatAndPreservesExistingHomeworkAndCounters() { var (vm, entries, session, student) = Build(); entries.Save(new ParticipationEntry { SessionId = session.Id, StudentId = student.Id, Homework = HomeworkStatus.Completed, RaisedHandCount = 3, CalledOnCount = 2 }); vm.CheckAttendanceCommand.Execute(null); var seat = vm.Seats[0]; Assert.True(seat.ShowQuickCheck); Assert.False(vm.Seats[1].ShowQuickCheck); seat.QuickNegativeCommand.Execute(null); var entry = entries.GetBySessionAndStudent(session.Id, student.Id)!; Assert.Equal(AttendanceStatus.ExcusePending, entry.Attendance); Assert.Equal(HomeworkStatus.Completed, entry.Homework); Assert.Equal(3, entry.RaisedHandCount); Assert.Equal(2, entry.CalledOnCount); Assert.Equal(1, seat.DisplayOpacity); seat.QuickPositiveCommand.Execute(null); Assert.Equal(AttendanceStatus.Present, entry.Attendance); } [Fact] public void Homework_UpdatesLegacyFlagAndPreservesAttendance() { var (vm, entries, session, student) = Build(); entries.Save(new ParticipationEntry { SessionId = session.Id, StudentId = student.Id, Attendance = AttendanceStatus.Late }); vm.CheckHomeworkCommand.Execute(null); vm.Seats[0].QuickNegativeCommand.Execute(null); var entry = entries.GetBySessionAndStudent(session.Id, student.Id)!; Assert.Equal(HomeworkStatus.MissingOpen, entry.Homework); Assert.True(entry.HomeworkMissing); Assert.Equal(AttendanceStatus.Late, entry.Attendance); vm.Seats[0].QuickPositiveCommand.Execute(null); Assert.Equal(HomeworkStatus.Completed, entry.Homework); Assert.False(entry.HomeworkMissing); vm.EndQuickCheckCommand.Execute(null); Assert.False(vm.Seats[0].ShowQuickCheck); Assert.True(vm.Seats[0].ShowNormalActions); } [Fact] public async Task SpecialCases_OpenAssessmentForClickedStudentAndSession() { var (vm, _, _, _) = Build(); var calls = 0; vm.OnAssessStudent = _ => { calls++; return Task.CompletedTask; }; vm.CheckAttendanceCommand.Execute(null); await vm.Seats[0].QuickSpecialCommand.ExecuteAsync(null); Assert.Equal(1, calls); } [Fact] public void ReadOnlyAndEmptySeats_CannotWriteQuickChecks() { var (vm, entries, session, _) = Build(readOnly: true); vm.CheckHomeworkCommand.Execute(null); vm.Seats[0].QuickNegativeCommand.Execute(null); vm.Seats[1].QuickPositiveCommand.Execute(null); Assert.False(vm.Seats[0].ShowQuickCheck); Assert.Empty(entries.GetBySession(session.Id)); } }