diff --git a/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs b/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs index 3ff9d7e..b71b22e 100644 --- a/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs +++ b/LehrerApp.Desktop.Tests/TimetableViewModelTests.cs @@ -345,20 +345,28 @@ public sealed class TimetableViewModelTests public async Task OpenWeekCell_LessonHeuteWaehrendUnterrichtszeit_OeffnetUnterrichtsmodus() { var group = new LearningGroup { Name = "Q1 Chemie" }; - var today = DateOnly.FromDateTime(DateTime.Today); + // Bewusst nicht der reale DateTime.Today-Wochentag: an einem Sa/So gäbe es dafür keine + // Kachel im Mo-Fr-Raster. Stattdessen ein beliebiger Wochentag der laufenden Kalenderwoche + // (Kachel existiert immer), dessen Datum per VM.Clock als "heute" simuliert wird (siehe + // TimetableViewModel.Clock - genau für solche Tests eingeführt). + var weekday = DayOfWeek.Monday; + var lessonDate = DateInCurrentWeek(weekday); var slots = new FakeTimetableSlots(); - slots.Add(new TimetableSlot { GroupId = group.Id, Weekday = today.DayOfWeek, PeriodNumber = 1 }); - var lesson = new Lesson { GroupId = group.Id, Date = today, LessonNumber = 1, Topic = "Redox" }; + slots.Add(new TimetableSlot { GroupId = group.Id, Weekday = weekday, PeriodNumber = 1 }); + var lesson = new Lesson { GroupId = group.Id, Date = lessonDate, LessonNumber = 1, Topic = "Redox" }; var lessons = new FakeLessons(); lessons.Add(lesson); var periodSchedule = BuildPeriodSchedule(1); var vm = BuildViewModel(slots, new FakeGroups([group]), lessons: lessons, periodSchedule: periodSchedule); + // Gleiche Uhrzeit wie BuildPeriodSchedule (reales DateTime.Now), aber am simulierten + // "heutigen" Datum - die Stundenzeit-Prüfung (Uhrzeit) bleibt so unabhängig vom Datum. + vm.Clock = () => lessonDate.ToDateTime(TimeOnly.FromDateTime(DateTime.Now)); Lesson? teachingModeLesson = null; Lesson? viewerLesson = null; vm.OnOpenTeachingMode = l => { teachingModeLesson = l; return Task.CompletedTask; }; vm.OnOpenLessonViewer = l => { viewerLesson = l; return Task.CompletedTask; }; - var cell = vm.WeekItems.Single(c => c.IsSlotCell && c.Weekday == today.DayOfWeek && c.PeriodNumber == 1); + var cell = vm.WeekItems.Single(c => c.IsSlotCell && c.Weekday == weekday && c.PeriodNumber == 1); await vm.OpenWeekCellCommand.ExecuteAsync(cell); Assert.Equal(lesson.Id, teachingModeLesson?.Id); diff --git a/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs b/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs index 2560bff..e6c30a3 100644 --- a/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs +++ b/LehrerApp.Desktop/ViewModels/Planning/TimetableViewModel.cs @@ -109,6 +109,11 @@ public partial class TimetableViewModel : ObservableObject public Func? OnOpenLessonViewer { get; set; } public Func? OnOpenTeachingMode { get; set; } + /// Öffentlich statt intern (kein InternalsVisibleTo in dieser Codebasis) - erlaubt Tests, die + /// "heute"-abhängiges Verhalten (Wochenraster-Badges, Unterrichtszeit-Erkennung) prüfen, ohne + /// vom tatsächlichen Wochentag/der Uhrzeit im Testlauf abzuhängen. + public Func Clock { get; set; } = () => DateTime.Now; + public TimetableViewModel(ITimetableSlotRepository slots, IGroupRepository groups, ISubjectRepository subjects, ILessonRepository lessons, IExamRepository exams, ISchoolHolidayRepository schoolHolidays, SchoolCalendarSettingsService calendarSettings, @@ -156,7 +161,7 @@ public partial class TimetableViewModel : ObservableObject public void Load() { - var today = DateOnly.FromDateTime(DateTime.Today); + var today = DateOnly.FromDateTime(Clock()); TodayLabel = today.ToString("dddd, dd.MM.yyyy", System.Globalization.CultureInfo.GetCultureInfo("de-DE")); var publicHolidayDates = new HashSet(); @@ -399,9 +404,10 @@ public partial class TimetableViewModel : ObservableObject private static readonly TimeSpan TeachingTimeTolerance = TimeSpan.FromMinutes(10); private bool IsAroundTeachingTime(DateOnly lessonDate, int periodNumber) { - if (lessonDate != DateOnly.FromDateTime(DateTime.Today)) return false; + var nowSnapshot = Clock(); + if (lessonDate != DateOnly.FromDateTime(nowSnapshot)) return false; if (_periodSchedule.GetTimes(periodNumber) is not { } times) return false; - var now = TimeOnly.FromDateTime(DateTime.Now); + var now = TimeOnly.FromDateTime(nowSnapshot); return now >= times.Start.Add(-TeachingTimeTolerance) && now <= times.End.Add(TeachingTimeTolerance); }