Stundenplan: Wochenend-Flakiness in Unterrichtsmodus-Test behoben
OpenWeekCell_LessonHeuteWaehrendUnterrichtszeit_OeffnetUnterrichtsmodus schlug an Sa/So fehl, weil today.DayOfWeek dort keiner Kachel im Mo-Fr-Wochenraster entspricht. TimetableViewModel bekommt dafür eine austauschbare Clock-Property (Standard: DateTime.Now), sodass der Test "heute" unabhängig vom tatsächlichen Wochentag simulieren kann. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -345,20 +345,28 @@ public sealed class TimetableViewModelTests
|
|||||||
public async Task OpenWeekCell_LessonHeuteWaehrendUnterrichtszeit_OeffnetUnterrichtsmodus()
|
public async Task OpenWeekCell_LessonHeuteWaehrendUnterrichtszeit_OeffnetUnterrichtsmodus()
|
||||||
{
|
{
|
||||||
var group = new LearningGroup { Name = "Q1 Chemie" };
|
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();
|
var slots = new FakeTimetableSlots();
|
||||||
slots.Add(new TimetableSlot { GroupId = group.Id, Weekday = today.DayOfWeek, PeriodNumber = 1 });
|
slots.Add(new TimetableSlot { GroupId = group.Id, Weekday = weekday, PeriodNumber = 1 });
|
||||||
var lesson = new Lesson { GroupId = group.Id, Date = today, LessonNumber = 1, Topic = "Redox" };
|
var lesson = new Lesson { GroupId = group.Id, Date = lessonDate, LessonNumber = 1, Topic = "Redox" };
|
||||||
var lessons = new FakeLessons();
|
var lessons = new FakeLessons();
|
||||||
lessons.Add(lesson);
|
lessons.Add(lesson);
|
||||||
var periodSchedule = BuildPeriodSchedule(1);
|
var periodSchedule = BuildPeriodSchedule(1);
|
||||||
var vm = BuildViewModel(slots, new FakeGroups([group]), lessons: lessons, periodSchedule: periodSchedule);
|
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? teachingModeLesson = null;
|
||||||
Lesson? viewerLesson = null;
|
Lesson? viewerLesson = null;
|
||||||
vm.OnOpenTeachingMode = l => { teachingModeLesson = l; return Task.CompletedTask; };
|
vm.OnOpenTeachingMode = l => { teachingModeLesson = l; return Task.CompletedTask; };
|
||||||
vm.OnOpenLessonViewer = l => { viewerLesson = 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);
|
await vm.OpenWeekCellCommand.ExecuteAsync(cell);
|
||||||
|
|
||||||
Assert.Equal(lesson.Id, teachingModeLesson?.Id);
|
Assert.Equal(lesson.Id, teachingModeLesson?.Id);
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ public partial class TimetableViewModel : ObservableObject
|
|||||||
public Func<Lesson, Task>? OnOpenLessonViewer { get; set; }
|
public Func<Lesson, Task>? OnOpenLessonViewer { get; set; }
|
||||||
public Func<Lesson, Task>? OnOpenTeachingMode { get; set; }
|
public Func<Lesson, Task>? 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<DateTime> Clock { get; set; } = () => DateTime.Now;
|
||||||
|
|
||||||
public TimetableViewModel(ITimetableSlotRepository slots, IGroupRepository groups,
|
public TimetableViewModel(ITimetableSlotRepository slots, IGroupRepository groups,
|
||||||
ISubjectRepository subjects, ILessonRepository lessons, IExamRepository exams,
|
ISubjectRepository subjects, ILessonRepository lessons, IExamRepository exams,
|
||||||
ISchoolHolidayRepository schoolHolidays, SchoolCalendarSettingsService calendarSettings,
|
ISchoolHolidayRepository schoolHolidays, SchoolCalendarSettingsService calendarSettings,
|
||||||
@@ -156,7 +161,7 @@ public partial class TimetableViewModel : ObservableObject
|
|||||||
|
|
||||||
public void Load()
|
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"));
|
TodayLabel = today.ToString("dddd, dd.MM.yyyy", System.Globalization.CultureInfo.GetCultureInfo("de-DE"));
|
||||||
|
|
||||||
var publicHolidayDates = new HashSet<DateOnly>();
|
var publicHolidayDates = new HashSet<DateOnly>();
|
||||||
@@ -399,9 +404,10 @@ public partial class TimetableViewModel : ObservableObject
|
|||||||
private static readonly TimeSpan TeachingTimeTolerance = TimeSpan.FromMinutes(10);
|
private static readonly TimeSpan TeachingTimeTolerance = TimeSpan.FromMinutes(10);
|
||||||
private bool IsAroundTeachingTime(DateOnly lessonDate, int periodNumber)
|
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;
|
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);
|
return now >= times.Start.Add(-TeachingTimeTolerance) && now <= times.End.Add(TeachingTimeTolerance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user